gpt4 book ai didi

c# - 如何使用 WebSockets 跟踪已建立的连接

转载 作者:太空狗 更新时间:2023-10-29 23:30:54 25 4
gpt4 key购买 nike

我正在尝试为跨平台设备提供实时聊天服务。问题是 System.Net.WebSockets命名空间不允许我直接跟踪已建立的连接。我可以获取当前连接的 sessionID 但我怎么能说执行以下操作 await socket.SendAsync(buffer, WebSocketMessageType.Text, CancellationToken.None)针对特定客户?

如果我可以使用 Microsoft.WebSockets , 我将有可能创建一个 WebSocketCollection()并做类似 client.Send(message) 的事情, 但我无法发送 ArraySegment<byte[]>通过它。我还认为这更适用于 AJAX 客户端和网站以及这些东西。

我现在有以下代码片段:

public class WSHandler : IHttpHandler
{
event NewConnectionEventHandler NewConnection;
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(ProcessWSChat);
}
}

public bool IsReusable { get { return false; } }
private async Task ProcessWSChat(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
int myHash = socket.GetHashCode();
while (true)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
WebSocketReceiveResult result = await socket.ReceiveAsync(
buffer, CancellationToken.None);
if (socket.State == WebSocketState.Open)
{
string userMessage = Encoding.ASCII.GetString(
buffer.Array, 0, result.Count);
userMessage = "You sent: " + userMessage + " at " +
DateTime.Now.ToLongTimeString() + " from ip " +
context.UserHostAddress.ToString();
buffer = new ArraySegment<byte>(
Encoding.ASCII.GetBytes(userMessage));
await socket.SendAsync(
buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
break;
}
}
}
}

如何扩展我的项目、保存 session /连接并调用特定用户连接以向其发送消息?

最佳答案

通常,您不会做那样的事情。 WebSocket 应该只是另一层或子系统的端点。例如,事件驱动架构。在连接时,您应该启动处理程序,从连接的套接字收集数据,如 cookie、URL 或其他任何东西,并通知其他具有该 cookie/url 的用户已连接到该套接字。

关于您的代码:

  • 不要在循环内声明读取缓冲区,你可以重用它。
  • WebSockets 始终以 UTF8 而非 ASCII 格式发送文本数据。

这将是在小型项目中跟踪用户的一种方式,但我建议您将 WebSocket 插入另一个消息基础设施,如 MassTransit:

public class WSHandler : IHttpHandler
{
public bool IsReusable { get { return false; } }

public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(ProcessWSChat);
}
}

static readonly ConcurrentDictionary<IPrincipal, WebSocket> _users = new ConcurrentDictionary<IPrincipal, WebSocket>();

private async Task ProcessWSChat(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[4096]);

//Identify user by cookie or whatever and create a user Object
var cookie = context.Cookies["mycookie"];
var url = context.RequestUri;

IPrincipal myUser = GetUser(cookie, url);

// Or uses the user that came from the ASP.NET authentication.
myUser = context.User;

_users.AddOrUpdate(myUser, socket, (p, w) => socket);

while (socket.State == WebSocketState.Open)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None)
.ConfigureAwait(false);
String userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);

userMessage = "You sent: " + userMessage + " at " +
DateTime.Now.ToLongTimeString() + " from ip " + context.UserHostAddress.ToString();
var sendbuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));

await socket.SendAsync(sendbuffer , WebSocketMessageType.Text, true, CancellationToken.None)
.ConfigureAwait(false);
}

// when the connection ends, try to remove the user
WebSocket ows;
if (_users.TryRemove(myUser, out ows))
{
if (ows != socket)
{
// whops! user reconnected too fast and you are removing
// the new connection, put it back
_users.AddOrUpdate(myUser, ows, (p, w) => ows);
}
}
}

private IPrincipal GetUser(HttpCookie cookie, Uri url)
{
throw new NotImplementedException();
}
}

关于c# - 如何使用 WebSockets 跟踪已建立的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26263306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com