public WebuSocket( string url, int baseReceiveBufferSize, Action OnConnected = null, Action <Queue <ArraySegment <byte> > > OnMessage = null, Action OnPinged = null, Action <WebuSocketCloseEnum> OnClosed = null, Action <WebuSocketErrorEnum, Exception> OnError = null, Dictionary <string, string> additionalHeaderParams = null ) { this.webSocketConnectionId = Guid.NewGuid().ToString(); this.baseReceiveBufferSize = baseReceiveBufferSize; this.base64Key = WebSocketByteGenerator.GeneratePrivateBase64Key(); var requstBytesAndHostAndPort = GenerateRequestData(url, additionalHeaderParams, base64Key); this.endPoint = new IPEndPoint(IPAddress.Parse(requstBytesAndHostAndPort.host), requstBytesAndHostAndPort.port); this.OnConnected = OnConnected; this.OnMessage = OnMessage; this.OnPinged = OnPinged; this.OnClosed = OnClosed; this.OnError = OnError; StartConnectAsync(requstBytesAndHostAndPort.requestDataBytes); }
public void Ping(Action OnPonged) { this.OnPonged = OnPonged; var pingBytes = WebSocketByteGenerator.Ping(); socketToken.sendArgs.SetBuffer(pingBytes, 0, pingBytes.Length); if (!socketToken.socket.SendAsync(socketToken.sendArgs)) { OnSend(socketToken.socket, socketToken.sendArgs); } }
private void PingReceived() { if (OnPinged != null) { OnPinged(); } var pongBytes = WebSocketByteGenerator.Pong(); socketToken.sendArgs.SetBuffer(pongBytes, 0, pongBytes.Length); if (!socketToken.socket.SendAsync(socketToken.sendArgs)) { OnSend(socketToken.socket, socketToken.sendArgs); } }
private void StartCloseAsync() { var closeEventArgs = new SocketAsyncEventArgs(); closeEventArgs.UserToken = socketToken; closeEventArgs.AcceptSocket = socketToken.socket; var closeData = WebSocketByteGenerator.CloseData(); closeEventArgs.SetBuffer(closeData, 0, closeData.Length); closeEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnDisconnected); if (!socketToken.socket.SendAsync(closeEventArgs)) { OnDisconnected(socketToken.socket, closeEventArgs); } }
public void Send(byte[] data) { if (socketToken.socketState != SocketState.OPENED) { WebuSocketErrorEnum ev = WebuSocketErrorEnum.UNKNOWN_ERROR; Exception error = null; switch (socketToken.socketState) { case SocketState.OPENING: { ev = WebuSocketErrorEnum.CONNECTING; error = new Exception("send error:" + "not yet connected."); break; } case SocketState.CLOSING: case SocketState.CLOSED: { ev = WebuSocketErrorEnum.ALREADY_DISCONNECTED; error = new Exception("send error:" + "connection was already closed. please create new connection by new WebuSocket()."); break; } } if (OnError != null) { OnError(ev, error); } return; } var payloadBytes = WebSocketByteGenerator.SendBinaryData(data); socketToken.sendArgs.SetBuffer(payloadBytes, 0, payloadBytes.Length); if (!socketToken.socket.SendAsync(socketToken.sendArgs)) { OnSend(socketToken.socket, socketToken.sendArgs); } }
private void OnReceived(object unused, SocketAsyncEventArgs args) { var token = (SocketToken)args.UserToken; if (args.SocketError != SocketError.Success) { switch (token.socketState) { case SocketState.CLOSING: case SocketState.CLOSED: { // already closing, ignore. return; } default: { // show error, then close or continue receiving. if (OnError != null) { var error = new Exception("receive error:" + args.SocketError.ToString() + " size:" + args.BytesTransferred); OnError(WebuSocketErrorEnum.RECEIVE_FAILED, error); } // connection is already closed. if (!IsSocketConnected(token.socket)) { if (OnClosed != null) { OnClosed(WebuSocketCloseEnum.CLOSED_WHILE_RECEIVING); } Disconnect(); return; } // continue receiving data. go to below. break; } } } if (args.BytesTransferred == 0) { throw new Exception("failed to receive. args.BytesTransferred = 0."); } // update as read completed. token.readableDataLength = token.readableDataLength + args.BytesTransferred; switch (token.socketState) { case SocketState.OPENING: { var lineEndCursor = ReadUpgradeLine(args.Buffer, 0, token.readableDataLength); if (lineEndCursor != -1) { var protocolData = new SwitchingProtocolData(Encoding.UTF8.GetString(args.Buffer, 0, lineEndCursor)); var expectedKey = WebSocketByteGenerator.GenerateExpectedAcceptedKey(base64Key); if (protocolData.securityAccept != expectedKey) { if (OnError != null) { var error = new Exception("WebSocket Key Unmatched."); OnError(WebuSocketErrorEnum.CONNECTION_KEY_UNMATCHED, error); } } token.socketState = SocketState.OPENED; if (OnConnected != null) { OnConnected(); } ReadyReceivingNewData(token); return; } // should read next. ReceivingRestDataWithoutSort(token); return; } case SocketState.OPENED: { var result = ScanBuffer(token.receiveBuffer, token.readableDataLength); // read completed datas. if (0 < result.segments.Count) { OnMessage(result.segments); } // if the last result index is matched to whole length, receive finished. if (result.lastDataTail == token.readableDataLength) { ReadyReceivingNewData(token); return; } // rest data exists. var alreadyReceivedDataLength = token.receiveBuffer.Length - result.lastDataTail; // should read rest. ReceivingRestData(token, result.lastDataTail, alreadyReceivedDataLength); return; } default: { var error = new Exception("fatal error, could not detect error, receive condition is strange, token.socketState:" + token.socketState); if (OnError != null) { OnError(WebuSocketErrorEnum.RECEIVE_FAILED, error); } Disconnect(true); return; } } }