客戶端。
<!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給客戶端。測試了這個方法是可行的。但就是不知道會有什么其他問題。
如果看到這篇文章,有更好解決辦法的朋友,留下個鏈接,非常感謝