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