private void HandleNewMessage(WebSocketReceiveResult msgInfo, byte[] buffer) { if (msgInfo == null) { return; } try { if (msgInfo.MessageType == WebSocketMessageType.Text) { var text = Encoding.UTF8.GetString(buffer, 0, buffer.Length); OnTextMessage?.Invoke(text); } else if (msgInfo.MessageType == WebSocketMessageType.Binary) { OnBinaryMessage?.Invoke(buffer); } } catch (Exception ex) { OnError?.Invoke(ex); } }
private void HandleMessage(OpCode opCode, byte[] data) { if (opCode == OpCode.Text) { OnTextMessage?.Invoke(this, Encoding.UTF8.GetString(data)); } else { OnBinaryMessage?.Invoke(this, data); } }
private async Task Receive(ClientWebSocket clientWebSocket, CancellationToken token, Action <string> handleMessage) { while (_clientWebSocket.State == WebSocketState.Open && !token.IsCancellationRequested) { ArraySegment <Byte> buffer = new ArraySegment <byte>(new Byte[1024 * 4]); WebSocketReceiveResult result = null; using (var ms = new MemoryStream()) { do { result = await clientWebSocket.ReceiveAsync(buffer, CancellationToken.None).ConfigureAwait(false); ms.Write(buffer.Array, buffer.Offset, result.Count); if (result.MessageType == WebSocketMessageType.Close) { break; } }while (!result.EndOfMessage); _lastReceivedMsg = DateTime.UtcNow; ms.Seek(0, SeekOrigin.Begin); if (result.MessageType == WebSocketMessageType.Text) { try { string serializedMessage = null; using (var reader = new StreamReader(ms, Encoding.UTF8)) { serializedMessage = await reader.ReadToEndAsync().ConfigureAwait(false); } OnTextMessage?.Invoke(this, new TextMessageEventArgs(serializedMessage)); //handleMessage(serializedMessage); } catch (Exception e) { } } else if (result.MessageType == WebSocketMessageType.Binary) { OnBinaryMessage?.Invoke(this, new BinaryMessageEventArgs()); } else if (result.MessageType == WebSocketMessageType.Close) { await _clientWebSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None).ConfigureAwait(false); _clientWebSocket = null; _cancelation.Cancel(); OnClose?.Invoke(this, new CloseEventArgs()); break; } } } }
private void InvokeEvent(LazyNotification lazyNotification) { var notification = lazyNotification.Notifications; switch (lazyNotification.NotifyType) { case NotificationType.ChannelCreated: break; case NotificationType.ChannelDeleted: break; case NotificationType.ChannelChanged: break; case NotificationType.ChannelEdited: break; case NotificationType.ChannelMoved: break; case NotificationType.ChannelPasswordChanged: break; case NotificationType.ClientEnterView: OnClientEnterView?.Invoke(this, notification.Cast <ClientEnterView>()); break; case NotificationType.ClientLeftView: OnClientLeftView?.Invoke(this, notification.Cast <ClientLeftView>()); break; case NotificationType.ClientMoved: break; case NotificationType.ServerEdited: break; case NotificationType.TextMessage: OnTextMessage?.Invoke(this, notification.Cast <TextMessage>()); break; case NotificationType.TokenUsed: break; // special case NotificationType.CommandError: break; case NotificationType.Unknown: default: throw Util.UnhandledDefault(lazyNotification.NotifyType); } }
private void InvokeEvent(LazyNotification lazyNotification) { var ntf = lazyNotification.Notifications; switch (lazyNotification.NotifyType) { case NotificationType.ChannelChanged: { var ntfc = (ChannelChanged[])ntf; OnChannelChanged?.Invoke(this, ntfc); var ev = OnEachChannelChanged; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ChannelCreated: { var ntfc = (ChannelCreated[])ntf; OnChannelCreated?.Invoke(this, ntfc); var ev = OnEachChannelCreated; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ChannelDeleted: { var ntfc = (ChannelDeleted[])ntf; OnChannelDeleted?.Invoke(this, ntfc); var ev = OnEachChannelDeleted; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ChannelEdited: { var ntfc = (ChannelEdited[])ntf; OnChannelEdited?.Invoke(this, ntfc); var ev = OnEachChannelEdited; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ChannelMoved: { var ntfc = (ChannelMoved[])ntf; OnChannelMoved?.Invoke(this, ntfc); var ev = OnEachChannelMoved; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ChannelPasswordChanged: { var ntfc = (ChannelPasswordChanged[])ntf; OnChannelPasswordChanged?.Invoke(this, ntfc); var ev = OnEachChannelPasswordChanged; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ClientEnterView: { var ntfc = (ClientEnterView[])ntf; OnClientEnterView?.Invoke(this, ntfc); var ev = OnEachClientEnterView; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ClientLeftView: { var ntfc = (ClientLeftView[])ntf; OnClientLeftView?.Invoke(this, ntfc); var ev = OnEachClientLeftView; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ClientMoved: { var ntfc = (ClientMoved[])ntf; OnClientMoved?.Invoke(this, ntfc); var ev = OnEachClientMoved; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.ServerEdited: { var ntfc = (ServerEdited[])ntf; OnServerEdited?.Invoke(this, ntfc); var ev = OnEachServerEdited; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.TextMessage: { var ntfc = (TextMessage[])ntf; OnTextMessage?.Invoke(this, ntfc); var ev = OnEachTextMessage; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.TokenUsed: { var ntfc = (TokenUsed[])ntf; OnTokenUsed?.Invoke(this, ntfc); var ev = OnEachTokenUsed; foreach (var that in ntfc) { ev?.Invoke(this, that); } break; } case NotificationType.CommandError: break; case NotificationType.Unknown: default: throw Tools.UnhandledDefault(lazyNotification.NotifyType); } }
private void InvokeEvent(LazyNotification lazyNotification) { var ntf = lazyNotification.Notifications; switch (lazyNotification.NotifyType) { case NotificationType.ChannelChanged: { var ntfc = (ChannelChanged[])ntf; ProcessChannelChanged(ntfc); OnChannelChanged?.Invoke(this, ntfc); var ev = OnEachChannelChanged; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelChanged(that); } break; } case NotificationType.ChannelCreated: { var ntfc = (ChannelCreated[])ntf; ProcessChannelCreated(ntfc); OnChannelCreated?.Invoke(this, ntfc); var ev = OnEachChannelCreated; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelCreated(that); book?.UpdateChannelCreated(that); } break; } case NotificationType.ChannelDeleted: { var ntfc = (ChannelDeleted[])ntf; ProcessChannelDeleted(ntfc); OnChannelDeleted?.Invoke(this, ntfc); var ev = OnEachChannelDeleted; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelDeleted(that); book?.UpdateChannelDeleted(that); } break; } case NotificationType.ChannelEdited: { var ntfc = (ChannelEdited[])ntf; ProcessChannelEdited(ntfc); OnChannelEdited?.Invoke(this, ntfc); var ev = OnEachChannelEdited; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelEdited(that); book?.UpdateChannelEdited(that); } break; } case NotificationType.ChannelGroupList: { var ntfc = (ChannelGroupList[])ntf; ProcessChannelGroupList(ntfc); OnChannelGroupList?.Invoke(this, ntfc); var ev = OnEachChannelGroupList; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelGroupList(that); } break; } case NotificationType.ChannelList: { var ntfc = (ChannelList[])ntf; ProcessChannelList(ntfc); OnChannelList?.Invoke(this, ntfc); var ev = OnEachChannelList; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelList(that); book?.UpdateChannelList(that); } break; } case NotificationType.ChannelListFinished: { var ntfc = (ChannelListFinished[])ntf; ProcessChannelListFinished(ntfc); OnChannelListFinished?.Invoke(this, ntfc); var ev = OnEachChannelListFinished; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelListFinished(that); } break; } case NotificationType.ChannelMoved: { var ntfc = (ChannelMoved[])ntf; ProcessChannelMoved(ntfc); OnChannelMoved?.Invoke(this, ntfc); var ev = OnEachChannelMoved; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelMoved(that); book?.UpdateChannelMoved(that); } break; } case NotificationType.ChannelPasswordChanged: { var ntfc = (ChannelPasswordChanged[])ntf; ProcessChannelPasswordChanged(ntfc); OnChannelPasswordChanged?.Invoke(this, ntfc); var ev = OnEachChannelPasswordChanged; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelPasswordChanged(that); } break; } case NotificationType.ChannelSubscribed: { var ntfc = (ChannelSubscribed[])ntf; ProcessChannelSubscribed(ntfc); OnChannelSubscribed?.Invoke(this, ntfc); var ev = OnEachChannelSubscribed; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelSubscribed(that); } break; } case NotificationType.ChannelUnsubscribed: { var ntfc = (ChannelUnsubscribed[])ntf; ProcessChannelUnsubscribed(ntfc); OnChannelUnsubscribed?.Invoke(this, ntfc); var ev = OnEachChannelUnsubscribed; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachChannelUnsubscribed(that); } break; } case NotificationType.ClientChannelGroupChanged: { var ntfc = (ClientChannelGroupChanged[])ntf; ProcessClientChannelGroupChanged(ntfc); OnClientChannelGroupChanged?.Invoke(this, ntfc); var ev = OnEachClientChannelGroupChanged; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientChannelGroupChanged(that); book?.UpdateClientChannelGroupChanged(that); } break; } case NotificationType.ClientChatComposing: { var ntfc = (ClientChatComposing[])ntf; ProcessClientChatComposing(ntfc); OnClientChatComposing?.Invoke(this, ntfc); var ev = OnEachClientChatComposing; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientChatComposing(that); } break; } case NotificationType.ClientDbIdFromUid: { var ntfc = (ClientDbIdFromUid[])ntf; ProcessClientDbIdFromUid(ntfc); OnClientDbIdFromUid?.Invoke(this, ntfc); var ev = OnEachClientDbIdFromUid; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientDbIdFromUid(that); } break; } case NotificationType.ClientEnterView: { var ntfc = (ClientEnterView[])ntf; ProcessClientEnterView(ntfc); OnClientEnterView?.Invoke(this, ntfc); var ev = OnEachClientEnterView; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientEnterView(that); book?.UpdateClientEnterView(that); } break; } case NotificationType.ClientIds: { var ntfc = (ClientIds[])ntf; ProcessClientIds(ntfc); OnClientIds?.Invoke(this, ntfc); var ev = OnEachClientIds; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientIds(that); } break; } case NotificationType.ClientLeftView: { var ntfc = (ClientLeftView[])ntf; ProcessClientLeftView(ntfc); OnClientLeftView?.Invoke(this, ntfc); var ev = OnEachClientLeftView; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientLeftView(that); book?.UpdateClientLeftView(that); } break; } case NotificationType.ClientMoved: { var ntfc = (ClientMoved[])ntf; ProcessClientMoved(ntfc); OnClientMoved?.Invoke(this, ntfc); var ev = OnEachClientMoved; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientMoved(that); book?.UpdateClientMoved(that); } break; } case NotificationType.ClientNeededPermissions: { var ntfc = (ClientNeededPermissions[])ntf; ProcessClientNeededPermissions(ntfc); OnClientNeededPermissions?.Invoke(this, ntfc); var ev = OnEachClientNeededPermissions; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientNeededPermissions(that); } break; } case NotificationType.ClientPoke: { var ntfc = (ClientPoke[])ntf; ProcessClientPoke(ntfc); OnClientPoke?.Invoke(this, ntfc); var ev = OnEachClientPoke; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientPoke(that); } break; } case NotificationType.ClientServerGroup: { var ntfc = (ClientServerGroup[])ntf; ProcessClientServerGroup(ntfc); OnClientServerGroup?.Invoke(this, ntfc); var ev = OnEachClientServerGroup; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientServerGroup(that); } break; } case NotificationType.ClientServerGroupAdded: { var ntfc = (ClientServerGroupAdded[])ntf; ProcessClientServerGroupAdded(ntfc); OnClientServerGroupAdded?.Invoke(this, ntfc); var ev = OnEachClientServerGroupAdded; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachClientServerGroupAdded(that); book?.UpdateClientServerGroupAdded(that); } break; } case NotificationType.CommandError: { var ntfc = (CommandError[])ntf; ProcessCommandError(ntfc); OnCommandError?.Invoke(this, ntfc); var ev = OnEachCommandError; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachCommandError(that); } break; } case NotificationType.ConnectionInfo: { var ntfc = (ConnectionInfo[])ntf; ProcessConnectionInfo(ntfc); OnConnectionInfo?.Invoke(this, ntfc); var ev = OnEachConnectionInfo; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachConnectionInfo(that); book?.UpdateConnectionInfo(that); } break; } case NotificationType.ConnectionInfoRequest: { var ntfc = (ConnectionInfoRequest[])ntf; ProcessConnectionInfoRequest(ntfc); OnConnectionInfoRequest?.Invoke(this, ntfc); var ev = OnEachConnectionInfoRequest; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachConnectionInfoRequest(that); } break; } case NotificationType.FileDownload: { var ntfc = (FileDownload[])ntf; ProcessFileDownload(ntfc); OnFileDownload?.Invoke(this, ntfc); var ev = OnEachFileDownload; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileDownload(that); } break; } case NotificationType.FileInfoTs: { var ntfc = (FileInfoTs[])ntf; ProcessFileInfoTs(ntfc); OnFileInfoTs?.Invoke(this, ntfc); var ev = OnEachFileInfoTs; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileInfoTs(that); } break; } case NotificationType.FileList: { var ntfc = (FileList[])ntf; ProcessFileList(ntfc); OnFileList?.Invoke(this, ntfc); var ev = OnEachFileList; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileList(that); } break; } case NotificationType.FileListFinished: { var ntfc = (FileListFinished[])ntf; ProcessFileListFinished(ntfc); OnFileListFinished?.Invoke(this, ntfc); var ev = OnEachFileListFinished; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileListFinished(that); } break; } case NotificationType.FileTransfer: { var ntfc = (FileTransfer[])ntf; ProcessFileTransfer(ntfc); OnFileTransfer?.Invoke(this, ntfc); var ev = OnEachFileTransfer; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileTransfer(that); } break; } case NotificationType.FileTransferStatus: { var ntfc = (FileTransferStatus[])ntf; ProcessFileTransferStatus(ntfc); OnFileTransferStatus?.Invoke(this, ntfc); var ev = OnEachFileTransferStatus; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileTransferStatus(that); } break; } case NotificationType.FileUpload: { var ntfc = (FileUpload[])ntf; ProcessFileUpload(ntfc); OnFileUpload?.Invoke(this, ntfc); var ev = OnEachFileUpload; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachFileUpload(that); } break; } case NotificationType.InitIvExpand: { var ntfc = (InitIvExpand[])ntf; ProcessInitIvExpand(ntfc); OnInitIvExpand?.Invoke(this, ntfc); var ev = OnEachInitIvExpand; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachInitIvExpand(that); } break; } case NotificationType.InitIvExpand2: { var ntfc = (InitIvExpand2[])ntf; ProcessInitIvExpand2(ntfc); OnInitIvExpand2?.Invoke(this, ntfc); var ev = OnEachInitIvExpand2; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachInitIvExpand2(that); } break; } case NotificationType.InitServer: { var ntfc = (InitServer[])ntf; ProcessInitServer(ntfc); OnInitServer?.Invoke(this, ntfc); var ev = OnEachInitServer; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachInitServer(that); book?.UpdateInitServer(that); } break; } case NotificationType.PluginCommand: { var ntfc = (PluginCommand[])ntf; ProcessPluginCommand(ntfc); OnPluginCommand?.Invoke(this, ntfc); var ev = OnEachPluginCommand; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachPluginCommand(that); } break; } case NotificationType.ServerEdited: { var ntfc = (ServerEdited[])ntf; ProcessServerEdited(ntfc); OnServerEdited?.Invoke(this, ntfc); var ev = OnEachServerEdited; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachServerEdited(that); book?.UpdateServerEdited(that); } break; } case NotificationType.ServerGroupList: { var ntfc = (ServerGroupList[])ntf; ProcessServerGroupList(ntfc); OnServerGroupList?.Invoke(this, ntfc); var ev = OnEachServerGroupList; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachServerGroupList(that); book?.UpdateServerGroupList(that); } break; } case NotificationType.TextMessage: { var ntfc = (TextMessage[])ntf; ProcessTextMessage(ntfc); OnTextMessage?.Invoke(this, ntfc); var ev = OnEachTextMessage; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachTextMessage(that); } break; } case NotificationType.TokenUsed: { var ntfc = (TokenUsed[])ntf; ProcessTokenUsed(ntfc); OnTokenUsed?.Invoke(this, ntfc); var ev = OnEachTokenUsed; var book = Book; foreach (var that in ntfc) { ev?.Invoke(this, that); ProcessEachTokenUsed(that); } break; } case NotificationType.Unknown: default: throw Util.UnhandledDefault(lazyNotification.NotifyType); } }
/// <summary> /// Awaitable task that reads incoming messages from the WebSocket. /// This is a blocking method /// </summary> /// <returns></returns> public async Task <ConnectionResult> ReadLoopAsync(CancellationToken ct) { while (!ct.IsCancellationRequested && !_disconnecting) { if (_ws.State != WebSocketState.Open) { TraceEvent( "(ReadLoopAsync) Invalid attempt to read a closed socket", EventIdentifiers.WS_ERR_READ_SOCK_CLOSE_ASYNC, TraceEventType.Error ); throw new InvalidOperationException("Websocket is not open"); } if (ct.IsCancellationRequested) { TraceEvent( "(ReadLoopAsync) Operation cancelled", EventIdentifiers.WS_WAR_CANC_READ, TraceEventType.Warning ); ct.ThrowIfCancellationRequested(); } await _sem.WaitAsync(ct); WebSocketReceiveResult res; ArraySegment <byte> buf = new ArraySegment <byte>(new byte[1024]); res = await _ws.ReceiveAsync(buf, ct); _sem.Release(); //We don't know how long the receive task has waited, so check for cancellation again if (ct.IsCancellationRequested) { TraceEvent( "(ReadLoopAsync) Operation cancelled", EventIdentifiers.WS_WAR_CANC_READ_ASYNC, TraceEventType.Warning ); ct.ThrowIfCancellationRequested(); } if (res.MessageType == WebSocketMessageType.Close) { _disconnecting = true; TraceEvent( $"(ReadLoopAsync) Close request: [{res.CloseStatus}] {res.CloseStatusDescription}", EventIdentifiers.WS_INF_CONN_CLOSE_REQ, TraceEventType.Information ); await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close request acknowledged", ct); TraceEvent( "(ReadLoopAsync) Socket disconnected", EventIdentifiers.WS_INF_CONN_CLOSE, TraceEventType.Information ); return(ConnectionResult.Disconnecting); } if (!res.EndOfMessage) { _rQ.Enqueue(buf.Take(res.Count)); continue; } List <byte> msg = new List <byte>(); while (!_rQ.IsEmpty) { _rQ.TryDequeue(out IEnumerable <byte> result); msg.AddRange(result); } msg.AddRange(buf.Take(res.Count)); TraceEvent( $"(ReadLoopAsync) Received bytes [ len: {res.Count} ]", EventIdentifiers.WS_VER_RBYTES_ASYNC, TraceEventType.Verbose ); if (res.MessageType == WebSocketMessageType.Binary) { OnBinaryMessage?.Invoke(this, new BinaryMessageEventArgs(msg.ToArray())); } else { string strMsg = Encoding.UTF8.GetString(msg.ToArray()); OnTextMessage?.Invoke(this, new StringMessageEventArgs(strMsg)); } } if (ct.IsCancellationRequested) { TraceEvent( "(ReadLoopAsync) Operation cancelled", EventIdentifiers.WS_WAR_CANC_READ_ASYNC, TraceEventType.Warning ); ct.ThrowIfCancellationRequested(); } TraceEvent( "(ReadLoopAsync) Socket disconnecting", EventIdentifiers.WS_INF_CONN_CLOSE, TraceEventType.Information ); return(ConnectionResult.Disconnecting); }