public WebSocketMessage CreateCloseMessage(string errorMessage, WebSocketCloseStatusCode closeStatusCode) { byte[] error = Encoding.UTF8.GetBytes(errorMessage.Trim()); if (error.Length > 123) { throw new Exception("close frame payload data length must be 0-125"); } List <WebSocketFragment> fragments = new List <WebSocketFragment>(); List <byte> list = new List <byte>(); Byte firstByte = 0x88; Byte secondByte = (Byte)error.Length; list.Add(firstByte); list.Add(secondByte); for (int j = 0; j < 2; j++) { Byte b = (Byte)((int)closeStatusCode >> 8 * j); list.Add(b); } for (int i = 0; i < error.Length; i++) { list.Add(error[i]); } WebSocketFragment fragment = new WebSocketFragment(list.ToArray()); fragments.Add(fragment); return(new WebSocketMessage(fragments)); }
private void ReceiveCallback(IAsyncResult ar) { WebSocketReceiveError error; ReceiveObject obj = (ReceiveObject)ar.AsyncState; int receiveLength = obj.Socket.EndReceive(ar); if (receiveLength > 0) { ArraySegment <byte> bytes = new ArraySegment <byte>(obj.Buffer, 0, receiveLength); WebSocketFragment fragment = messageHandler.Parse(bytes.ToArray(), out error); if (error != null) { Close(error.CloseReason, error.CloseStatusCode); obj.Error(obj.Session, error); WebSocketSessionContainer sessions = (WebSocketSessionContainer)obj.State; sessions.Remove(SessionID); } else { if (fragment.Opcode == WebSocketOpcode.Ping) { WebSocketMessage m = messageHandler.CreatePong(fragment.PayloadData); Send(m); } else if (fragment.Opcode == WebSocketOpcode.Pong) { } else if (fragment.Opcode == WebSocketOpcode.Close) { Close("Normal Close", WebSocketCloseStatusCode.Normal); obj.Error(obj.Session, new WebSocketReceiveError() { CloseReason = "Normal Close", CloseStatusCode = WebSocketCloseStatusCode.Normal }); WebSocketSessionContainer sessions = (WebSocketSessionContainer)obj.State; sessions.Remove(SessionID); } else { obj.Message.Fragments.Add(fragment); if (fragment.IsFinal) { obj.Success(obj.Session, obj.Message); obj.Message = new WebSocketMessage(); } } } } if (serverSocket.Connected) { serverSocket.BeginReceive(obj.Buffer, 0, serverSocket.ReceiveBufferSize, SocketFlags.None, ReceiveCallback, obj); } }
public WebSocketMessage CreatePing() { List <WebSocketFragment> fragments = new List <WebSocketFragment>(); List <byte> list = new List <byte>(); Byte firstByte = 0x89; Byte sencondByte = 0x0; list.Add(firstByte); list.Add(sencondByte); WebSocketFragment fragment = new WebSocketFragment(list.ToArray()); fragments.Add(fragment); return(new WebSocketMessage(fragments)); }
public WebSocketMessage CreatePong(byte[] pingdata) { if (pingdata.Length > 125) { throw new Exception("pong frame payload data length must be 0-125"); } List <WebSocketFragment> fragments = new List <WebSocketFragment>(); List <byte> list = new List <byte>(); Byte firstByte = 0x8a; Byte sencondByte = (Byte)pingdata.Length; list.Add(firstByte); list.Add(sencondByte); for (int i = 0; i < pingdata.Length; i++) { list.Add(pingdata[i]); } WebSocketFragment fragment = new WebSocketFragment(list.ToArray()); fragments.Add(fragment); return(new WebSocketMessage(fragments)); }
public WebSocketMessage CreateMessage(byte[] sendBytes, int buffersize, string messagetype) { if (messagetype != "text" && messagetype != "binary") { throw new Exception("messagetype is not surport,must be text or bianry"); } List <WebSocketFragment> fragments = new List <WebSocketFragment>(); int payloadLength = (buffersize - 10); int count = sendBytes.Length / payloadLength; int rest = sendBytes.Length % payloadLength; if (rest != 0) { count++; } for (int i = 0; i < count; i++) { List <byte> list = new List <byte>(); Byte firstbyte = 0; if (i == count - 1) { firstbyte = (Byte)(firstbyte | 0x80); } if (i == 0 && messagetype == "text") { firstbyte = (Byte)(firstbyte | 0x1); } if (i == 0 && messagetype == "binary") { firstbyte = (Byte)(firstbyte | 0x2); } list.Add(firstbyte); Byte sencondByte = 0; int size = rest == 0 ? payloadLength : (i == count - 1) ? rest : payloadLength; if (size >= 0 && size <= 125) { sencondByte = (Byte)(sencondByte | size); list.Add(sencondByte); } else if (size > 125 && size <= 65535) { sencondByte = (Byte)(sencondByte | 0x7e); list.Add(sencondByte); for (int j = 1; j >= 0; j--) { Byte b = (Byte)(size >> 8 * j); list.Add(b); } } else { sencondByte = (Byte)(sencondByte | 0x7f); list.Add(sencondByte); for (int j = 7; j >= 0; j--) { Byte b = (Byte)(size >> 8 * j); list.Add(b); } } for (int n = 0; n < size; n++) { list.Add(sendBytes[payloadLength * i + n]); } WebSocketFragment fragment = new WebSocketFragment(list.ToArray()); fragments.Add(fragment); } return(new WebSocketMessage(fragments)); }
public WebSocketFragment Parse(byte[] receiveBytes, out WebSocketReceiveError error) { error = null; WebSocketFragment fragment = new WebSocketFragment(receiveBytes); #region validate if (fragment.IsExtensionNegotiated) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "RSV1,RSV2,RSV3 must be 0,because extension negotiation is not supported" }; } if (fragment.IsFinal && fragment.Opcode == WebSocketOpcode.Continuation) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "FIN is set to 1 but opcode indicate a contituation" }; } if (fragment.Opcode == WebSocketOpcode.ReservedNoncontrolframe) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Opcode 3-7 is reserved for non-control frames and is not suported now" }; } if (fragment.Opcode == WebSocketOpcode.ReservedControlframe) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Opcode B-F is reserved for controlframes and is not suported now" }; } if (fragment.IsFinal && fragment.Opcode == WebSocketOpcode.Ping) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Ping frame can not be fragmented" }; } if (fragment.IsFinal && fragment.Opcode == WebSocketOpcode.Pong) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Pong frame can not be fragmented" }; } if (fragment.IsFinal && fragment.Opcode == WebSocketOpcode.Close) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Close frame can not be fragmented" }; } if (fragment.Opcode == WebSocketOpcode.Unkown) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Unkown Opcode" }; } if (!fragment.IsMasked) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "Message send from client must be masked" }; } if (fragment.PayloadLength != (ulong)fragment.PayloadData.Length) { error = new WebSocketReceiveError() { CloseStatusCode = WebSocketCloseStatusCode.ProtocolError, CloseReason = "payloadlength field value does not match the length of received payload data" }; } #endregion return(fragment); }