【发布时间】:2017-10-27 00:58:29
【问题描述】:
我对 C# 编程非常陌生,以前只使用过 Java。我正在构建的这个项目应该非常简单——我们有一个包含一系列外币对的网页。选择的元素被发送到服务器,服务器以硬编码的汇率值进行响应。要求是这两个操作都是通过使用 WebSocket 来实现的。这是我页面上的JS代码:
var protocol;
var wsUri;
var socket;
window.onload = function(e) {
e.preventDefault();
protocol = location.protocol === "https:" ? "wss:" : "ws:";
wsUri = protocol + "//" + window.location.host;
socket = new WebSocket(wsUri);
socket.onopen = e => {
console.log("socket opened", e);
};
document.getElementById("currencypair").onchange = function()
{
var selector = document.getElementById("currencypair");
var text = selector.options[selector.selectedIndex].text;
socket.send(text);
};
socket.onmessage = function (evt) {
var receivedMessage = evt.data;
document.getElementById("output").html(receivedMessage);
};
};
这里是Startup.cs类Configure方法的sn-p:
app.UseWebSockets();
app.UseMiddleware<WebSocketMiddleware>();
这是处理请求的中间件类。
public class WebSocketMiddleware
{
private readonly RequestDelegate _next;
public WebSocketMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await _next.Invoke(context);
return;
}
var ct = context.RequestAborted;
using (var socket = await context.WebSockets.AcceptWebSocketAsync())
{
while (true)
{
var stringReceived = await ReceiveStringAsync(socket, ct);
if (CurrencyPairCollection.CurrencyPairs.TryGetValue(stringReceived, out var value))
{
await SendStringAsync(socket, value.ToString(), ct);
}
else
{
throw new Exception("Unexpected value");
}
await Task.Delay(1000, ct);
}
}
}
private static async Task<string> ReceiveStringAsync(WebSocket socket, CancellationToken ct = default(CancellationToken))
{
var buffer = new ArraySegment<byte>();
using (var ms = new MemoryStream())
{
WebSocketReceiveResult result;
do
{
ct.ThrowIfCancellationRequested();
result = await socket.ReceiveAsync(buffer, ct);
ms.Write(buffer.Array, buffer.Offset, result.Count);
}
while (!result.EndOfMessage);
ms.Seek(0, SeekOrigin.Begin);
if (result.MessageType != WebSocketMessageType.Text || result.Count.Equals(0))
{
throw new Exception("Unexpected message");
}
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
return await reader.ReadToEndAsync();
}
}
}
private static Task SendStringAsync(WebSocket socket, string data, CancellationToken ct = default(CancellationToken))
{
var segment = new ArraySegment<byte>(Encoding.UTF8.GetBytes(data));
return socket.SendAsync(segment, WebSocketMessageType.Text, true, ct);
}
}
请注意,我正在使用以下示例,其中包含评论部分中人们列出的错误。我尽力解决了这些问题,但是由于我的经验有限,这可能是问题所在。
https://www.softfluent.com/blog/dev/Using-Web-Sockets-with-ASP-NET-Core
基本上,在运行应用程序时,浏览器控制台会立即报告: WebSocket 连接到“ws://localhost:51017/”失败:WebSocket 握手期间出错:意外响应代码:200
【问题讨论】:
-
这本身不是一个答案,但也许你应该考虑使用 SignalR,它会让你的生活变得轻松 ;-) 但是我看到你正在使用 .Net Core 并且 SignalR 仅适用于 .NET Core 2.1 所以你必须使用每晚构建直到年底(2.1-preview1)
-
是的,我可能会尝试一下。问题是,要求是 WebSockets。不过还是谢谢。
-
我不明白。 SignalR 正在使用网络套接字。
-
.NET Core 2.0 也是必须的:) 这是一个面试后收到的项目。
-
有人有什么建议吗?我今天需要交这个...