【问题标题】:Websocket custom server not working with firefox, but working with ChromeWebsocket 自定义服务器不能与 firefox 一起使用,但可以与 Chrome 一起使用
【发布时间】:2019-10-26 01:56:56
【问题描述】:

我正在使用 c# 编写自定义 Websocket 服务器。我根据this mozilla 指南编写了一些代码。现在我成功地握手并从我的客户端接收消息,并且所有这些都在 Chrome 上运行,但是当我尝试从 FireFox 上的服务器发送消息时,我收到控制台错误“与 ws://localhost:80 的连接是页面加载时中断”。我正在发送编码消息,使用来自this page 的算法和来自websocket echo test 的客户端完全相同。你可以在GitHub找到整个项目

我尝试发送不编码字节并在每次发送消息时重新打开 websoket 连接)。

如您所见,服务器自动向客户端发送消息“Hello”。 处理函数(每个客户端的新线程):

public void Process()
        {           
            try
            {
                Stream = _client.GetStream();
                HandShake();
                while (true)
                {                  
                  while (_client.Available < 3)
                  {

                  }

                  Byte[] bytes = new Byte[_client.Available];
                  Stream.Read(bytes, 0, bytes.Length);
                  var message = GetMessage(bytes);
                    if (_webSocketConverter.IsClosing(bytes[0]))
                  {       

                      break;
                  }

                   message = GetMessage(bytes);
                  SendMessageFromServer("Hello");         

                }                
            }
            catch (Exception ex)
            {
                throw ex;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
                Console.ResetColor();               
            }
            finally
            {
                _server.RemoveConnection(this._userInfo.Id);
                Console.WriteLine("Client {0} disconnected from the server", this._userInfo.Id);
                Close();
            }
        }

SendMessage 函数(EncodeMessage - 来自上面链接的算法,很好地与 chrome 配合使用)

private void SendMessageFromServer(string message)
        {
            Byte[] messageByte = _webSocketConverter.EncodeMessage(message);            
            Stream.Write(messageByte);
        }

似乎是服务器的问题,因为 websocket.org/echo 使用 firefox。

【问题讨论】:

  • 如果我没记错的话,Firefox 在Upgrade 标头中使用了不同的大小写字母(类似于WebSocket 而不是websocket)你必须确保你正在测试任何字母大小写组合。
  • 试过了,不行。从官方Mozilla网站获得标题,它应该是正确的。还尝试添加协议“聊天”,也不起作用
  • 我用 Firefox 标头发布了一个答案,并注意到奇怪的 Connection 标头。我怀疑这是原因。我很抱歉我的记忆误导了我关于奇怪标题的身份。

标签: javascript c# firefox websocket server


【解决方案1】:

谢谢大家的回答。发现问题!这是我的编码函数(wesocketconverter.cs)。我将格式化数组初始化为 raw array.length + 10。所以,我得到了 8 个额外的空字节。 Chrome 处理它,当额外的字节是偶数时,但火狐没有。迟早它会在 chrome 上结束工作。

【讨论】:

    【解决方案2】:

    一个可能的解决方案可能与 Firefox Connection 标头有关。

    比较 Chrome 和 Firefox 上的 WebSocket 连接请求会发现,Firefox 上的 Connection 标头是 "keep-alive, Upgrade" 而不是 "Upgrade"(在 Chrome 上)。

    一种可能的解决方案是测试标头中是否存在Upgrade(不区分大小写),而不是测试标头的完全相等性。

    Chrome 上的完整 WebSocket 请求(在我的机器上)如下所示:

    Read: GET /HTTP/1.1
    Host: localhost:3000
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade: websocket
    Origin: http://localhost:3000
    Sec-WebSocket-Version: 13
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-US,en;q=0.9
    Sec-WebSocket-Key: NmFGZCcMdiNlXoW/R+F0lw==
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
    

    而 Firefox 上的完整 WebSocket 请求为:

    GET / HTTP/1.1
    Host: localhost:3000
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
    Accept: */*
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Sec-WebSocket-Version: 13
    Origin: http://localhost:3000
    Sec-WebSocket-Extensions: permessage-deflate
    Sec-WebSocket-Key: QU6J0KFZjDA/OgVSATpYDg==
    Connection: keep-alive, Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade: websocket
    

    【讨论】:

    • 非常感谢您的回答,非常感谢您的关注。
    • @EduardSemenkin - 当然,我很乐意提供帮助。如果答案有助于解决您的问题,请接受(将其标记为已接受)。您总是可以“接受”您提出的问题的答案。如果他们有帮助,也可以随意投票给答案:-) ...(尽管我知道我的回答可能没有太大帮助)
    • 无论如何,谢谢你的帮助。我怎样才能给你点赞之类的? stackoverflow 的新手
    • @EduardSemenkin ,没关系,无论如何我很乐意提供帮助,不需要其他任何东西。一般来说,在 SO 中,我们不会向人们提供“喜欢”,只是回答。这样,有用的答案会向上传播,使整个开发者社区受益,而无用的答案会逐渐消失。我的回答对你没有帮助。如果其他人觉得它有帮助,他们可能会支持它。如果不是,它只是证明它应该消失。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 2012-07-14
    相关资源
    最近更新 更多