node-ews icon indicating copy to clipboard operation
node-ews copied to clipboard

Streaming Request?

Open kcastrotech opened this issue 8 years ago • 7 comments

I'm playing around with the EWS streaming subscription and am wondering if there is a way to access the streaming request as data comes in instead of waiting until it finishes?

For example, if I create a subscription then use the "GetStreamingEvents" function like so:

		ews.run("GetStreamingEvents",{
			SubscriptionIds:{
				SubscriptionId:this.subscriptionId
			},
			ConnectionTimeout:1
		}).then(events => {
			//Do something with events
		}, err => {
			//Ooops, something went wrong!
		});

The "then(events => {..." isn't called until after the connection times out (e.g. 1 minute) and the response at that point contains multiple envelopes with or without events:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:Notifications>
						<m:Notification>
							<t:SubscriptionId>FQBjYmNkY21haWwwMy5jYmNrYy5vcmcQAAAAvxnM8b2nh0C6cdPzWYkpp2wPU82pgtQIEAAAACGRLXGSJlZJn4ZVwqpDTtI=</t:SubscriptionId>
							<t:CreatedEvent>
								<t:TimeStamp>2017-04-13T20:15:37Z</t:TimeStamp>
								<t:ItemId Id="AAH8Bh99AAA=" ChangeKey="CQAAAA==" />
								<t:ParentFolderId Id="AAAqoK/AAA=" ChangeKey="AQAAAA==" />
							</t:CreatedEvent>
							<t:NewMailEvent>
								<t:TimeStamp>2017-04-13T20:15:37Z</t:TimeStamp>
								<t:ItemId Id="yHL73BAAH8Bh99AAA=" ChangeKey="CQAAAA==" />
								<t:ParentFolderId Id="AAAAqoK/AAA=" ChangeKey="AQAAAA==" />
							</t:NewMailEvent>
							<t:ModifiedEvent>
								<t:TimeStamp>2017-04-13T20:15:37Z</t:TimeStamp>
								<t:FolderId Id="3iAAqoK/AAA=" ChangeKey="AQAAAA==" />
								<t:ParentFolderId Id="3iAAAAqoK8AAA=" ChangeKey="AQAAAA==" />
								<t:UnreadCount>2</t:UnreadCount>
							</t:ModifiedEvent>
						</m:Notification>
					</m:Notifications>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:ConnectionStatus>OK</m:ConnectionStatus>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:ConnectionStatus>OK</m:ConnectionStatus>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:Notifications>
						<m:Notification>
							<t:SubscriptionId>FQBjYmNkY21haWwwMy5jYmNrYy5vcmcQAAAAvxnM8b2nh0C6cdPzWYkpp2wPU82pgtQIEAAAACGRLXGSJlZJn4ZVwqpDTtI=</t:SubscriptionId>
							<t:ModifiedEvent>
								<t:TimeStamp>2017-04-13T20:16:59Z</t:TimeStamp>
								<t:ItemId Id="AA99AAA=" ChangeKey="CQAAAA==" />
								<t:ParentFolderId Id="AAMkADc/AAA=" ChangeKey="AQAAAA==" />
							</t:ModifiedEvent>
							<t:ModifiedEvent>
								<t:TimeStamp>2017-04-13T20:16:59Z</t:TimeStamp>
								<t:FolderId Id="AAMkAAAA=" ChangeKey="AQAAAA==" />
								<t:ParentFolderId Id="AAMoK8AAA=" ChangeKey="AQAAAA==" />
								<t:UnreadCount>1</t:UnreadCount>
							</t:ModifiedEvent>
						</m:Notification>
					</m:Notifications>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:ConnectionStatus>OK</m:ConnectionStatus>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:ConnectionStatus>OK</m:ConnectionStatus>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1076" MinorBuildNumber="9" Version="V2_22" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
	</soap11:Header>
	<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
		<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
			<m:ResponseMessages>
				<m:GetStreamingEventsResponseMessage ResponseClass="Success">
					<m:ResponseCode>NoError</m:ResponseCode>
					<m:ConnectionStatus>Closed</m:ConnectionStatus>
				</m:GetStreamingEventsResponseMessage>
			</m:ResponseMessages>
		</m:GetStreamingEventsResponse>
	</soap11:Body>
</Envelope>

So what I need to do is tap into the request as it's running and parse the streaming data as it comes in.

I've been digging through the node-ews and node-soap code but am not seeing anything that can allow me to do that without forking it. I was hoping someone here may have another idea or knows of something that I've missed?

Thanks in advance!

kcastrotech avatar Apr 17 '17 15:04 kcastrotech

We are already on a modified fork of node-soap to fix a recursion issue with stack overflow when parsing the MS wdsl. If it makes sense to, we can modify that fork? Otherwise, been thinking of replacing node-soap completely, but yet to find the time to research another library.

nmarus avatar May 18 '17 12:05 nmarus

I ended up putting this on the back burner and focusing on push notifications instead which I was able to get working with minimal modifications. However, I think I've got an idea on how to do this.

It would appear that the node-soap HttpClient (soap\lib\http.js:21) accepts options.request as an option that later gets used to make the eventual request to the soap server. I then tracked the wsdlOptions object and it would appear that it gets passed along to wsdl.open_wsdl whereby it is then used to create a new HttpClient (soap\lib\wsdl.js:2149). I think I can tap into that by passing a custom function as wsdlOptions.request that wraps the request module. Then I should be able to intercept the request and pipe (https://github.com/request/request#streaming) it to a function that can process the incoming stream.

If that works then no modifications should be needed. I'll keep everyone posted on how it goes.

kcastrotech avatar May 18 '17 16:05 kcastrotech

Also, have you seen strong-soap? (https://github.com/strongloop/strong-soap) I haven't played with it yet but it might be a suitable alternative and would seem to fit in node-ews perfectly with little to no modification. I'm just not sure about the stack overflow issue. But if I get a chance I'll replace node-soap with that and let you know how it goes. Can you link me to the original issue and fix for the stack overflow problem so I can be sure to test properly?

kcastrotech avatar May 18 '17 16:05 kcastrotech

Issue #17 and fork of node this lib uses is here: https://github.com/CumberlandGroup/node-soap with modified code here: https://github.com/CumberlandGroup/node-soap/commit/aafad446344ef858d424126061287376893edc8e

The issue is node-soap does a LOT of recursive function without a process.nexttick, while the MS wsdl has a lot of self referencing logic. (=boom) See here for some details on this with javascript and recursion: http://stackoverflow.com/questions/28349548/how-does-process-nexttick-keep-my-stack-from-blowing-up

nmarus avatar May 18 '17 22:05 nmarus

Oh yeah... I remember that issue now! :)

kcastrotech avatar May 19 '17 00:05 kcastrotech

Moved over to the updated version of node-soap (19.2) in version 3.2.x. Im curious if this is working now?

nmarus avatar Aug 05 '17 21:08 nmarus

Has this issue been fixed aready? I still encounter the Problem

PatrickUrlberger avatar Mar 23 '21 12:03 PatrickUrlberger