123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Security.Cryptography;
- namespace HPSocketCS
- {
- public class WebSocketServer : HttpServer
- {
- public event WebSocketEvent.OnWSMessageHeaderEventHandler OnWSMessageHeader;
- public event WebSocketEvent.OnWSMessageBodyEventHandler OnWSMessageBody;
- public event WebSocketEvent.OnPointerWSMessageBodyEventHandler OnPointerWSMessageBody;
- public event WebSocketEvent.OnWSMessageCompleteEventHandler OnWSMessageComplete;
- HttpSdk.OnWSMessageHeader _OnWSMessageHeader;
- HttpSdk.OnWSMessageBody _OnWSMessageBody;
- HttpSdk.OnWSMessageComplete _OnWSMessageComplete;
- protected override void SetCallback()
- {
- base.SetCallback();
- // 设置websocket的callback
- _OnWSMessageHeader = new HttpSdk.OnWSMessageHeader(SDK_OnWSMessageHeader);
- _OnWSMessageBody = new HttpSdk.OnWSMessageBody(SDK_OnWSMessageBody);
- _OnWSMessageComplete = new HttpSdk.OnWSMessageComplete(SDK_OnWSMessageComplete);
- HttpSdk.HP_Set_FN_HttpServer_OnWSMessageHeader(pListener, _OnWSMessageHeader);
- HttpSdk.HP_Set_FN_HttpServer_OnWSMessageBody(pListener, _OnWSMessageBody);
- HttpSdk.HP_Set_FN_HttpServer_OnWSMessageComplete(pListener, _OnWSMessageComplete);
-
- }
- protected virtual HandleResult SDK_OnWSMessageHeader(IntPtr pSender, IntPtr dwConnID, bool bFinal, byte iReserved, byte iOperationCode, byte[] lpszMask, ulong ullBodyLen)
- {
- if (OnWSMessageHeader != null)
- {
- return OnWSMessageHeader(dwConnID, bFinal, iReserved, iOperationCode, lpszMask, ullBodyLen);
- }
- return HandleResult.Ok;
- }
- protected virtual HandleResult SDK_OnWSMessageBody(IntPtr pSender, IntPtr dwConnID, IntPtr pData, int length)
- {
- if (OnPointerWSMessageBody != null)
- {
- return OnPointerWSMessageBody(dwConnID, pData, length);
- }
- else if (OnWSMessageBody != null)
- {
- byte[] bytes = new byte[length];
- Marshal.Copy(pData, bytes, 0, length);
- return OnWSMessageBody(dwConnID, bytes);
- }
- return HandleResult.Ok;
- }
- protected virtual HandleResult SDK_OnWSMessageComplete(IntPtr pSender, IntPtr connId)
- {
- if (OnWSMessageComplete != null)
- {
- return OnWSMessageComplete(connId);
- }
- return HandleResult.Ok;
- }
- protected override HttpParseResult SDK_OnUpgrade(IntPtr pSender, IntPtr connId, HttpUpgradeType upgradeType)
- {
- if (upgradeType == HttpUpgradeType.HttpTunnel)
- {
- SendResponse(connId, HttpStatusCode.Ok, "Connection Established", null, null, 0);
- }
- else if (upgradeType == HttpUpgradeType.WebSocket)
- {
- THeader[] headers =
- {
- new THeader() { Name= "Connection", Value = "Upgrade" },
- new THeader() { Name= "Upgrade", Value = "WebSocket" },
- new THeader(),
- new THeader(),
- };
- var keyName = "Sec-WebSocket-Key";
- var secWebSocketKey = GetHeader(connId, keyName);
- if (string.IsNullOrEmpty(secWebSocketKey))
- {
- return HttpParseResult.Error;
- }
- SHA1 sha1 = new SHA1CryptoServiceProvider();
- byte[] bytes_sha1_in = Encoding.UTF8.GetBytes(secWebSocketKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
- byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in);
- string str_sha1_out = Convert.ToBase64String(bytes_sha1_out);
- headers[2].Name = "Sec-WebSocket-Accept";
- headers[2].Value = str_sha1_out;
- var secWebSocketProtocol = GetHeader(connId, "Sec-WebSocket-Protocol");
- if (!string.IsNullOrEmpty(secWebSocketProtocol))
- {
- var arr = secWebSocketProtocol.Split(new[] { ',', ' ' });
- if (arr.Length > 0)
- {
- headers[3].Name = "Sec-WebSocket-Protocol";
- headers[3].Value = arr[0];
- }
- }
- SendResponse(connId, HttpStatusCode.SwitchingProtocols, null, headers, null, 0);
- }
- return HttpParseResult.Ok;
- }
- public bool SendMessage(IntPtr connId, WSMessageState state, IntPtr pData, int length)
- {
- return HttpSdk.HP_HttpServer_SendWSMessage(pServer, connId, state.Final, state.Reserved, state.OperationCode, state.Mask, pData, length, 0);
- }
- public bool SendWSMessage(IntPtr connId, WSMessageState state, byte[] data)
- {
- state.Mask = null;
- int bodyLen = data == null ? 0 : data.Length;
- return HttpSdk.HP_HttpServer_SendWSMessage(pServer, connId, state.Final, state.Reserved, state.OperationCode, state.Mask, data, bodyLen, 0);
- }
- public WSMessageState GetWSMessageState(IntPtr connId)
- {
- bool final = false;
- WSReserved reserved = WSReserved.Off;
- WSOpcode operationCode = WSOpcode.Cont;
- IntPtr maskPtr = IntPtr.Zero;
- ulong bodyLen = 0;
- ulong bodyRemain = 0;
- bool ret = HttpSdk.HP_HttpServer_GetWSMessageState(pServer, connId, ref final, ref reserved, ref operationCode, ref maskPtr, ref bodyLen, ref bodyRemain);
- if (ret)
- {
- WSMessageState state = new WSMessageState()
- {
- Final = final,
- Reserved = reserved,
- OperationCode = operationCode,
- BodyLen = bodyLen,
- BodyRemain = bodyRemain,
- };
- if (maskPtr != IntPtr.Zero)
- {
- state.Mask = new byte[4];
- Marshal.Copy(maskPtr, state.Mask, 0, state.Mask.Length);
- }
- return state;
- }
- return null;
- }
- }
- }
|