@(WebSocket服务 .NET向)
WebSocket服务端的实现 前言时隔多日终于下定决心写关于websocket相关的内容,接下来我会介绍websocket服务端如何封装。
HTTP 与 WebSocket之间的区别http是单向的,只能由浏览器(客户端)发起请求,服务器(服务端)只负责接收处理信息,并返回结果,而websocket是双向的,可以由服务端发起请求到客户端,或者客户端发起请求到服务端,例如聊天室功能。
定义WebsocketConnected模型public class WebSocketConnected
{
public IPEndPoint RemoteEndPoint { get; set; }
public WebSocket WebSocket { get; set; }
}
WebSocketConnected 模型结构如下:
| Field | Description |
|---|---|
| RemoteEndPoint | 客户端地址 |
| WebSocket |
public interface IWebSocketOperate
{
Action OnMessage { get; set; }
Action OnOpen { get; set; }
Action OnClose { get; set; }
Action OnError { get; set; }
void Send(string text);
void Send(string text, IPEndPoint point);
}
IWebSocketOperate具体功能用途如下:
| Method | Description |
|---|---|
| OnMessage | 接收客户端消息时 |
| OnOpen | 客户端连接时 |
| OnClose | 客户端关闭连接时 |
| OnError | 服务端出现异常时 |
| Send | 服务端发送消息到服务端 |
public class WebSocketOperate : IWebSocketOperate
{
private HttpListener _httpListener;
public Action OnMessage { get; set; }
public Action OnOpen { get; set; }
public Action OnClose { get; set; }
public Action OnError { get; set; }
public WebSocketOperate(HttpListener httpListener, Action initialize)
{
try
{
initialize(this);
_httpListener = httpListener;
_httpListener.Start();
Console.WriteLine($"Service on Running ws://{httpListener.Prefixes.First().Replace("http://", string.Empty)}");
while (true)
{
HttpListenerContext ctx = _httpListener.GetContext();
OnOpen?.Invoke();
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), ctx);
}
}
catch (Exception ex)
{
OnError?.Invoke(ex.Message);
}
}
//用于保存连接数据
static List websContainer = new List();
WebSocket currWs;
public async void TaskProc(object ctx)
{
HttpListenerContext context = ctx as HttpListenerContext;
byte[] buf = new byte[1024];
ArraySegment abuf = new ArraySegment(buf);
CancellationToken cancel = CancellationToken.None;
HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null, TimeSpan.FromDays(1));
WebSocket ws = webSocketContext.WebSocket;
currWs = webSocketContext.WebSocket;
WebSocketConnected webConected = new WebSocketConnected { RemoteEndPoint = context.Request.RemoteEndPoint, WebSocket = ws };
websContainer.Add(webConected);
while (true)
{
if (ws.State ==WebSocketState.CloseReceived)
{
OnClose?.Invoke(context);
websContainer.Remove(webConected);
ws.Abort();
break;
}
var wsdata = await ws.ReceiveAsync(abuf, cancel);
Console.WriteLine(wsdata.Count);
byte[] bRec = new byte[wsdata.Count];
Array.Copy(buf, bRec, wsdata.Count);
OnMessage?.Invoke(Encoding.UTF8.GetString(bRec));
}
}
入口文件
public class WebSocketService
{
private HttpListener httpListener;
public WebSocketService(string uriPrefix)
{
httpListener = new HttpListener();
httpListener.Prefixes.Add(uriPrefix);
}
public void Start(Action webSockets)
{
WebSocketOperate operate = new WebSocketOperate(httpListener,webSockets);
}
}
程序的具体应用方法
static void Main(string[] argv)
{
WebSocketService ws = new WebSocketService("http://127.0.0.1:1500/");
ws.Start(socket =>
{
socket.OnOpen = () =>
{
Console.WriteLine("Open");
};
socket.OnClose = (ws1) =>
{
Console.WriteLine($"{ws1.Request.RemoteEndPoint.ToString()}");
};
socket.OnMessage = (msg) =>
{
if (msg == "1")
{
socket.Send("abc");
}
else
{
socket.Send("def");
}
Console.WriteLine(msg);
};
});
}
你们的支持就是我创作的动力



