使用ASP.NET核心websocket进行Unicode接收
我正在尝试使用ASP.NET core 1.1 websocket中间件构建一个websocket服务器,该中间件可以处理文本消息。我的策略是使用固定大小的缓冲区持续读取和解码,直到websocket消息结束。 中间件设置如下所示:使用ASP.NET核心websocket进行Unicode接收,websocket,asp.net-core,asp.net-core-middleware,Websocket,Asp.net Core,Asp.net Core Middleware,我正在尝试使用ASP.NET core 1.1 websocket中间件构建一个websocket服务器,该中间件可以处理文本消息。我的策略是使用固定大小的缓冲区持续读取和解码,直到websocket消息结束。 中间件设置如下所示: public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.Add
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
var logger = loggerFactory.CreateLogger("websocket");
app.UseWebSockets();
app.Use(async (http, next) =>
{
if (!http.WebSockets.IsWebSocketRequest)
{
await next();
return;
}
var websocket = await http.WebSockets.AcceptWebSocketAsync();
while (websocket.State == WebSocketState.Open)
{
var buffer = new ArraySegment<byte>(new byte[32]);
var charbuffer = new char[32];
try
{
var sb = new StringBuilder();
var decoder = Encoding.UTF8.GetDecoder();
//aha, we got a message
var detectResult = await websocket.ReceiveAsync(buffer, CancellationToken.None);
var receiveResult = detectResult;
while (!receiveResult.EndOfMessage)
{
var charLen = decoder.GetChars(buffer.Array, 0, receiveResult.Count, charbuffer, 0);
logger.LogInformation($"Decoded {charLen} byte(s) from wire");
sb.Append(charbuffer, 0, charLen);
receiveResult = await websocket.ReceiveAsync(buffer, CancellationToken.None);
}
var charLenFinal = decoder.GetChars(buffer.Array, 0, receiveResult.Count, charbuffer, 0);
logger.LogInformation($"Decoded {charLenFinal} byte(s) from wire");
sb.Append(charbuffer, 0, charLenFinal);
var message = sb.ToString();
logger.LogInformation($"decoded message: {message}");
await websocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes("got it")), WebSocketMessageType.Text, true, CancellationToken.None);
}
catch (Exception ex)
{
logger.LogError(ex.Message);
logger.LogError(ex.InnerException?.Message ?? string.Empty);
}
}
});
}
这个错误的原因是什么?我认为:
var charLenFinal = decoder.GetChars(buffer.Array, 0, receiveResult.Count, charbuffer, 0);
应该是:
var charLenFinal = decoder.GetChars(buffer.Array, 0, receiveResult.Count, charbuffer, 0, true);
自:
请记住,Decoder对象在调用之间保存状态
盖查斯。当应用程序使用数据流完成时,它
应将flush参数设置为true,以确保
信息被刷新。使用此设置,解码器将忽略无效
字节,并清除内部缓冲区
.奇怪,这些似乎没有关系,这个错误只是说客户端断开了连接。你的客户有什么问题吗?@Tratcher我不这么认为。它适用于ASCII文本和Unicode,其大小小于缓冲区大小(本例中为32)
var charLenFinal = decoder.GetChars(buffer.Array, 0, receiveResult.Count, charbuffer, 0);
var charLenFinal = decoder.GetChars(buffer.Array, 0, receiveResult.Count, charbuffer, 0, true);