【发布时间】:2018-06-30 07:04:55
【问题描述】:
您好,我有以下问题:
我正在尝试通过websockets 将对象从Console Application 发送到ASP NET Core Server。
在Console 应用程序上,我使用NewtonSoft Json 序列化一个对象,然后通过Socket 将其发送到.NET Core 服务器。
在服务器上,我创建了一个小型中间件。Invoke 方法只是没有被调用。
我保持两个 Visual Studio 实例处于打开状态,服务器端没有任何反应,直到我关闭客户端连接,服务器端弹出此错误 - 终端:
1 服务器
1.1 程序
class Program
{
static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)=>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel()
.UseSockets()
.UseUrls("http://localhost:8200")
.Build();
}
1.2 启动类
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<WebSocketService>(x=>new WebSocketService());
}
public void Configure(IApplicationBuilder builder)
{
builder.UseWebSockets();
builder.UseMiddleware<SocketMiddleware>();
}
}
1.3 中间件
class SocketMiddleware
{
WebSocketService handler;
public SocketMiddleware(WebSocketService _handler,RequestDelegate del)
{
this.handler = _handler;
this.next = del;
}
RequestDelegate next;
public async Task Invoke(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await this.next(context);
return;
}
await this.handler.AddClientAsync(context.WebSockets);
}
}
注意:我不会发布中间件使用的服务的代码,因为它与这种情况无关。invoke 不会被调用。
2 客户
客户端只是序列化一个 POCO 类 Player 并通过套接字发送它。然后它等待服务器响应 Player 列表。
static async Task Main(string[] args)
{
Player updatePlayer = new Player(100);
List<Player> players;
Memory<byte> buffer = new byte[2000];
ReadOnlyMemory<byte> toSend;
ReadOnlyMemory<byte> actualReceived;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8200);
Random rand = new Random();
await socket.ConnectAsync(iPEndPoint);
using(NetworkStream stream =new NetworkStream(socket))
{
while (true)
{
updatePlayer.Lat = rand.Next(10, 100);
updatePlayer.Lng = rand.Next(10, 100);
string data=JsonConvert.SerializeObject(updatePlayer);
toSend = Encoding.UTF8.GetBytes(data);
await stream.WriteAsync(toSend);
int received=await stream.ReadAsync(buffer);
actualReceived = buffer.Slice(0, received);
string msg = Encoding.UTF8.GetString(actualReceived.ToArray());
players = JsonConvert.DeserializeObject<List<Player>>(msg);
if (Console.ReadKey().Key == ConsoleKey.Escape)
{
break;
}
}
}
}
P.S 服务器使用websockets 并且在客户端我使用socket 类可能是一个问题吗?我认为只要目标地址和端口都可以..它只是字节。
【问题讨论】:
-
“我不会发布中间件使用的服务的代码,因为它与这种情况无关。” – 不确定我是否同意。您的中间件请求被中断了,因此您与 Web 套接字请求的交互方式确实很重要。话虽如此,您确定您的客户端工作吗?您是否尝试改用浏览器?另外,日志中还有其他内容吗?
-
我已经尝试过 chrome 提供的 websocket 客户端,它可以工作。我也尝试过 angular 2 js 客户端,它仍然有效。
Invoke方法被调用。为什么@ 987654341@不会调用它?我想可能是我发送了原始Tcp而.NET 框架需要HTTP GET? -
你检查WebSocket specification了吗? WebSockets 不仅仅是裸 TCP 套接字,它们是 HTTP 连接的升级,所以你不能仅仅打开一个这样的套接字并期望能够发送数据。
-
是的,我知道首先您发送一个 HTTP 请求,该请求将升级到 websocket(原始 tcp)。但是您如何包装您的请求来做到这一点?我的意思是带有一个原始套接字应该如何在 C# 中处理?
-
如果你想使用原始 TCP 套接字,你必须自己实现协议。否则,您可能应该使用 WebSocket 客户端库。
标签: asp.net-core websocket .net-core middleware