【问题标题】:Sending headers with websocket connection request (Mojolicious)使用 websocket 连接请求发送标头 (Mojolicious)
【发布时间】:2018-09-14 16:34:05
【问题描述】:

我需要从 Perl 打开一个与服务器的 websocket 连接。我让它在 echo.websocket.org 上工作,但是当我用真实服务器替换 websocket.org 时,握手失败。我怀疑我需要发送一些额外的标题,但我不确定该怎么做。我正在使用 Mojolicious 进行连接:

use strict;

use Mojo::UserAgent;
use Mojo::IOLoop;

# Open WebSocket
my $ua = Mojo::UserAgent->new;
$ua->websocket('wss://someserver.com/' => {
'Origin' => 'https://www.myserver.com',
'Sec-WebSocket-Extensions' => 'permessage-deflate'
} => sub {
  my ($ua, $tx) = @_;

  # Check if WebSocket handshake was successful
  unless( $tx->is_websocket ) {
    print "Handshake failed!\n";
    return;
  }

  # Wait for WebSocket to be closed
  $tx->on(finish => sub {
    my ($tx, $code, $reason) = @_;
    print "WebSocket closed with status $code.\n";
  });

  # Close WebSocket after receiving one message
  $tx->on(message => sub {
    my ($tx, $msg) = @_;
    print "WebSocket message: $msg\n";
    $tx->finish;
  });

  # Send a message to the server
  $tx->send("Hello world!");
});

# Start event loop if necessary
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

print "Done.\n";

如您所见,我正在尝试添加两个请求标头:OriginSec-WebSocket-Extensions

这是正确的方法吗?我问是因为握手仍然失败。

【问题讨论】:

  • 您实质上是在询问如何解决发生在一台服务器上而不是另一台服务器上的问题 - 没有提供有关另一台服务器的任何可用信息以及它究竟是如何失败的。这使得无法理解问题发生的原因并为您提供帮助。相反,您似乎无缘无故地随意摆弄一些额外的标题。而且,您不能只添加一些任意的 Sec-WebSocket-Extensions 标头而不实际支持给定的扩展。
  • 好吧,问题是:“如何向 websocket 连接请求添加额外的标头”。问题不是“这里有什么问题”。就像我说的,我怀疑缺少某些标头是这里的问题,但我不能确定,因为我无法在 Majolicious 文档中找到如何发送多个标头。所以这是我的第一个问题:“这是发送额外标头的方式吗?”
  • 如果您只想知道这是否是添加标题的正确方法:是的,它是also documented as such。为什么它仍然失败:不知道,因为不清楚您的服务器期望什么以及您的代码究竟是如何失败的。例如,它可能在 SSL 握手期间已经失败,甚至在它发送任何 HTTP 标头之前。
  • 我知道文档说明了如何设置“Sec-WebSocket-Extensions”标头。但它没有提到您可以以相同的方式设置任意标题。如果可以的话,我想知道我所做的是否是发送 multiple 标头的正确方法。
  • 该文档甚至还有一个设置DNT 标头的示例。是的,您可以一次以这种方式设置多个标题(刚刚尝试过),而且您也以正确的方式进行了设置。

标签: perl websocket mojolicious


【解决方案1】:

一种正确的方法可能是在每次执行 http 请求时设置标头,其中还应包括 Web 套接字类型的请求...并且以 Web 套接字服务器端指定的方式...

my $ua  = Mojo::UserAgent->new;
$ua->on(start => sub {
   my ($ua, $tx) = @_;
   $tx->req->headers->header('Sec-WebSocket-Extensions' => 'foo-bar-extensions');
   $tx->req->headers->header('Origin' => 'foo-bar-origin'); 
});

$ua->websocket('ws://my.server/jsonecho' => sub {
   my ($ua, $tx) = @_;
   say 'WebSocket handshake failed!' and return unless $tx->is_websocket;
   $tx->on(json => sub {
   my ($tx, $hash) = @_;
   say "WebSocket message via JSON: $hash->{msg}";
   $tx->finish;
   });
   $tx->send({json => {msg => 'Hello World!'}});
 });

【讨论】:

    猜你喜欢
    • 2020-10-15
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多