客户端。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <title></title> <script src="~/Scripts/jquery-1.10.2.min.js"></script> <script> var ws; $().ready(function () { $('#conn').click(function () { var wsUrl = 'ws://localhost:2925/api/HomeApi/GetWebSocket?user=' + $("#user").val() + "'"; ws = new WebSocket(wsUrl); $('#msg').append('<p>正在连接</p>'); ws.onopen = function () { $('#msg').append('<p>已经连接</p>'); } ws.onmessage = function (evt) { $('#msg').append('<p>' + evt.data + '</p>'); } ws.onerror = function (evt) { $('#msg').append('<p>' + JSON.stringify(evt) + '</p>'); } ws.onclose = function () { $('#msg').append('<p>已经关闭</p>'); } }); $('#close').click(function () { ws.close(); }); $('#send').click(function () { if (ws.readyState == WebSocket.OPEN) { ws.send($("#to").val() + "|" + $('#content').val()); } else { $('#tips').text('连接已经关闭'); } }); }); </script> </head> <body> <div> <input id="user" type="text" /> <input id="conn" type="button" value="连接" /> <input id="close" type="button" value="关闭" /><br /> <span id="tips"></span> <input id="content" type="text" /> <input id="send" type="button" value="发送" /><br /> <input id="to" type="text" />目的用户 <div id="msg"> </div> </div> </body> </html>
服务端
public HttpResponseMessage GetWebSocket(string user) { if (System.Web.HttpContext.Current.IsWebSocketRequest) { System.Web.HttpContext.Current.AcceptWebSocketRequest(ProcessWSChat); } return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols); } private async Task ProcessWSChat(AspNetWebSocketContext arg) { try { var socket = arg.WebSocket; #region 发送信息 开一个子线程 await Task.Factory.StartNew(() => MyMethod(socket)); #endregion //循环接收消息 while (true) { #region 接收信息 ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]); //保持状态 WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); //如果客户端发送了信息。 if (socket.State == WebSocketState.Open) { string message = Encoding.UTF8.GetString(buffer.Array, 0, result.Count); string returnMessage = "You send :" + message + ". at" + DateTime.Now.ToLongTimeString(); //发送消息,告诉客户端,我收到了。 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(returnMessage)); await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); } else { break; } #endregion } } catch (Exception ex) { throw; } } static void MyMethod(WebSocket socket) { int i = 0; int d = new Random().Next(9); while (true) { i++; if ((i % d) == 0) { if (socket.State == WebSocketState.Open) { //发送消息,告诉客户端,我收到了。 var buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes($"服务器发过去的.{i}")); socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); } else { break; } } Thread.Sleep(1000); } }
网上找的没有 : await Task.Factory.StartNew(() => MyMethod(socket));
这是自己写的。网上的会一直在这一步等待(WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);)
由于这步一直等待,不知道要如何让服务器主动发送消息,如果服务器无法发送消息,不是和http没什么区别了么?一样是等待客户端发送消息过来。
后来自己想了个办法,重新开了个线程。执行while,把需要推送的消息(如查询数据库获得的消息)send给客户端。测试了这个方法是可行的。但就是不知道会有什么其他问题。
如果看到这篇文章,有更好解决办法的朋友,留下个链接,非常感谢