客户端。
<!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给客户端。测试了这个方法是可行的。但就是不知道会有什么其他问题。
如果看到这篇文章,有更好解决办法的朋友,留下个链接,非常感谢
