public void Listen() { if (IsConnected) { try { //First wait for the Ams header (starts new thread) byte[] amsheader = new byte[AmsHeaderHelper.AmsTcpHeaderSize]; ListenForHeader(amsheader, (buffer, usertoken) => { //If a ams header is received, then read the rest (this is the new thread) try { byte[] response = GetAmsMessage(buffer); #if DEBUG_AMS Debug.WriteLine("Received bytes: " + ByteArrayHelper.ByteArrayToTestString(buffer) + ',' + ByteArrayHelper.ByteArrayToTestString(response)); #endif var syncContext = synchronizationContext; if (usertoken != null) { syncContext = usertoken as SynchronizationContext; } var callbackArgs = new AmsSocketResponseArgs() { Response = response, Context = syncContext }; OnReadCallBack(this, callbackArgs); Listen(); } catch (Exception ex) { var callbackArgs = new AmsSocketResponseArgs() { Error = ex }; OnReadCallBack(this, callbackArgs); } }); } catch (Exception ex) { if (!Object.ReferenceEquals(ex.GetType(), typeof(ObjectDisposedException))) { throw; } } } }
public void Send(byte[] message) { Trace.WriteLine("message: " + ByteArrayHelper.ByteArrayToTestString(message)); Trace.WriteLine("sendmsg: " + ByteArrayHelper.ByteArrayToTestString(SendMessage)); Assert.IsTrue(message.SequenceEqual(SendMessage)); int length = ReceiveMessage.Length - 6; byte[] response = new byte[length]; Array.Copy(ReceiveMessage, 6, response, 0, length); var callbackArgs = new AmsSocketResponseArgs() { Response = response }; OnReadCallBack(this, callbackArgs); }
//This is different thread! private void ReadCallback(object sender, AmsSocketResponseArgs args) { if (args.Error != null) { // Lock the list. lock (pendingResultsLock) { if (pendingResults.Count > 0) { foreach (var adsCommandResult in pendingResults.ToList()) { adsCommandResult.UnknownException = args.Error; adsCommandResult.Callback.Invoke(adsCommandResult); } } else { throw args.Error; } } } if ((args.Response != null) && (args.Response.Length > 0) && (args.Error == null)) { uint amsErrorCode = AmsHeaderHelper.GetErrorCode(args.Response); uint invokeId = AmsHeaderHelper.GetInvokeId(args.Response); bool isNotification = (AmsHeaderHelper.GetCommandId(args.Response) == AdsCommandId.DeviceNotification); if (AmsPortTarget != AmsHeaderHelper.GetAmsPortSource(args.Response)) { return; } if (!AmsNetIdTarget.Bytes.SequenceEqual(AmsHeaderHelper.GetAmsNetIdSource(args.Response))) { return; } //If notification then just start the callback if (isNotification && (OnNotification != null)) { var notifications = AdsNotification.GetNotifications(args.Response); foreach (var notification in notifications) { var notificationRequest = NotificationRequests.FirstOrDefault(n => n.NotificationHandle == notification.NotificationHandle); if (notificationRequest != null) { notificationRequest.ByteValue = notification.ByteValue; if ((args.Context != null) && (RunNotificationsOnMainThread)) { args.Context.Post( new SendOrPostCallback(delegate { OnNotification(null, new AdsNotificationArgs(notificationRequest)); }), null); } else { OnNotification(null, new AdsNotificationArgs(notificationRequest)); } } } } //If not a notification then find the original command and call async callback if (!isNotification) { AdsCommandResponse adsCommandResult = null; // Do some locking before fiddling with the list. lock (pendingResultsLock) { adsCommandResult = pendingResults.FirstOrDefault(r => r.CommandInvokeId == invokeId); if (adsCommandResult == null) { return; } //throw new AdsException("I received a response from a request I didn't send?"); pendingResults.Remove(adsCommandResult); } if (amsErrorCode > 0) { adsCommandResult.AmsErrorCode = amsErrorCode; } else { adsCommandResult.SetResponse(args.Response); } adsCommandResult.Callback.Invoke(adsCommandResult); } } }
private void Listen() { if ((socket != null) && (socket.Connected)) { try { //First wait for the Ams header (starts new thread) byte[] amsheader = new byte[AmsHeaderHelper.AmsTcpHeaderSize]; SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.SetBuffer(amsheader, 0, AmsHeaderHelper.AmsTcpHeaderSize); args.UserToken = synchronizationContext; args.Completed += (sender, e) => { //If a ams header is received, then read the rest (this is the new thread) try { byte[] response = GetAmsMessage(e.Buffer); Debug.WriteLine("Received bytes: " + ByteArrayHelper.ByteArrayToTestString(e.Buffer) + ',' + ByteArrayHelper.ByteArrayToTestString(response)); var callbackArgs = new AmsSocketResponseArgs() { Response = response, Context = e.UserToken as SynchronizationContext }; OnReadCallBack(this, callbackArgs); Listen(); } catch (Exception ex) { var callbackArgs = new AmsSocketResponseArgs() { Error = ex }; OnReadCallBack(this, callbackArgs); } }; if (!socket.ReceiveAsync(args)) { //If finished in same thread byte[] response = GetAmsMessage(amsheader); var callbackArgs = new AmsSocketResponseArgs() { Response = response, Context = synchronizationContext }; OnReadCallBack(this, callbackArgs); Listen(); } ; } catch (Exception ex) { if (!Object.ReferenceEquals(ex.GetType(), typeof(ObjectDisposedException))) { throw; } } } }