public class ChatClient
{
public string token { get; set; }
public string rnd { get; set; }
public WebSocket socket { get; set; }
}
public class SaasWebChat
{
static ILogger _log;
private static List<ChatClient> CONNECT_POOL = new List<ChatClient>();//用户连接池
public async static Task ProcessChat(AspNetWebSocketContext context)
{
_log = IocManager.Instance.Resolve<ILogger>();
WebSocket socket = context.WebSocket;
string token = context.QueryString["token"].ToString();
string rnd = context.QueryString["rnd"].ToString();
try
{
#region 用户添加连接池
//第一次open时,添加到连接池中
var row = CONNECT_POOL.FirstOrDefault(t => t.token == token && t.rnd == rnd);
if (row == null)
{
CONNECT_POOL.Add(new ChatClient
{
socket = socket,
token = token,
rnd = rnd
});//不存在,添加
_log.Debug(rnd + "连接成功");
}
#endregion
string descUser = string.Empty;//目的用户
while (true)
{
if (socket.State == WebSocketState.Open)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
#region 消息处理(字符截取、消息转发)
try
{
#region 关闭Socket处理,删除连接池
if (socket.State != WebSocketState.Open)//连接关闭
{
var client = CONNECT_POOL.FirstOrDefault(t => t.token == token && t.rnd == rnd);
if (client != null) CONNECT_POOL.Remove(client);//删除连接池
_log.Debug(client.rnd + "断开连接");
break;
}
#endregion
string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
string[] msgList = userMsg.Split('|');
if (msgList.Length == 2)
{
if (msgList[0].Trim().Length > 0)
descUser = msgList[0].Trim();//记录消息目的用户
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
var clientOnline = CONNECT_POOL.Where(t => t.token == descUser);
foreach (var item in clientOnline)
{
if (clientOnline != null)//判断客户端是否在线
{
WebSocket destSocket = item.socket;//目的客户端
if (destSocket != null && destSocket.State == WebSocketState.Open)
{
await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
_log.Debug(item.rnd + "发送消息");
}
}
}
}
else
{
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
foreach (var item in CONNECT_POOL)
{
await item.socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
_log.Debug(item.rnd + "发送消息");
}
}
}
catch (Exception exs)
{
//消息转发异常处理,本次消息忽略 继续监听接下来的消息
_log.Debug(rnd + "断开连接", exs);
}
#endregion
}
else
{
break;
}
}//while end
}
catch (Exception ex)
{
var clientEx = CONNECT_POOL.FirstOrDefault(t => t.token == token && t.rnd == rnd);
//整体异常处理
if (clientEx != null)
{
CONNECT_POOL.Remove(clientEx);
_log.Debug(clientEx.rnd + "断开连接", ex);
}
}
}
public static void SendMessage(string token, string data)
{
_log = IocManager.Instance.Resolve<ILogger>();
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(data));
var clientOnline = CONNECT_POOL.Where(t => t.token == token);//目的客户端
foreach (var item in clientOnline)
{
try
{
if (item.socket != null && item.socket.State == WebSocketState.Open)
{
item.socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
_log.Debug(item.rnd + "发送消息");
}
}
catch (Exception ex)
{
CONNECT_POOL.Remove(item);
_log.Debug(item.rnd + "断开连接",ex);
}
}
}
}
问题解决了,由于域名使用代理,5分钟刷新一次,导致连接中断
建议文字描述一下遇到的问题
– dudu 5年前@dudu:建立连接后,几分钟后,会在 WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);这里抛出异常,异常信息为WebSocketException (0x80070026): 已到文件结尾
– Chavez.net 5年前