简述:我使用Cro和websocket在互联网服务器上创建了一个服务。使用Cro示例非常简单。当页面作为localhost提供服务时,从HTML页面发送和接收数据没有问题。但是当页面使用https提供服务时,无法建立websocket连接。 如何使用Cro使用wss协议?
更新:安装cro
并运行cro stub :secure
后,service.p6文件中有一些文档中未明确说明的代码。
更多细节:
我有一个在互联网服务器上运行的docker文件,Cro设置为监听35145端口,因此docker命令为docker --rm -t myApp -p 35145:35145
服务文件包含以下内容:
use Cro::HTTP::Log::File;
use Cro::HTTP::Server;
use Cro::HTTP::Router;
use Cro::HTTP::Router::WebSocket;
my $host = %*ENV<RAKU_WEB_REPL_HOST> // '0.0.0.0';
my $port = %*ENV<RAKU_WEB_REPL_PORT> // 35145;
my Cro::Service $http = Cro::HTTP::Server.new(
http => <1.1>,
:$host,
:$port,
application => routes(),
after => [
Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
]
);
$http.start;
react {
whenever signal(SIGINT) {
say "Shutting down...";
$http.stop;
done;
}
}
sub routes() {
route {
get -> 'raku' {
web-socket :json, -> $incoming {
supply whenever $incoming -> $message {
my $json = await $message.body;
if $json<code> {
my $stdout, $stderr;
# process code
emit({ :$stdout, :$stderr })
}
}
}
}
}
}
在HTML中,我有一个带有id
raku-code
的文本区域容器。js脚本在DOM准备就绪后触发的处理程序中具有以下内容(我在脚本的其他位置设置了websocketHost和websocketPort):const connect = function() {
// Return a promise, which will wait for the socket to open
return new Promise((resolve, reject) => {
// This calculates the link to the websocket.
const socketProtocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:');
const socketUrl = `${socketProtocol}//${websocketHost}:${websocketPort}/raku`;
socket = new WebSocket(socketUrl);
// This will fire once the socket opens
socket.onopen = (e) => {
// Send a little test data, which we can use on the server if we want
socket.send(JSON.stringify({ "loaded" : true }));
// Resolve the promise - we are connected
resolve();
}
// This will fire when the server sends the user a message
socket.onmessage = (data) => {
let parsedData = JSON.parse(data.data);
const resOut = document.getElementById('raku-ws-stdout');
const resErr = document.getElementById('raku-ws-stderr');
resOut.textContent = parsedData.stdout;
resErr.textContent = parsedData.stderr;
}
设置了此JS脚本的HTML文件并在本地提供服务时,我可以将数据发送到在互联网服务器上运行的Cro应用程序,并且Cro应用程序(在docker映像中运行)处理并返回放置在正确的HTML容器中的数据。使用Firefox和开发人员工具,我可以看到ws连接已创建。
但是,当我通过强制访问https来通过Apache提供相同的文件时,Firefox发出错误,表示无法创建'wss'连接。此外,如果我在JS脚本中强制执行“ws”连接,则Firefox会阻止创建非安全连接。
a) 如何更改Cro编码以允许使用wss?从Cro文档中看来,我需要添加一个Cro :: TLS侦听器,但不清楚在哪里实例化侦听器。 b) 如果要将其放在Docker文件中,我是否需要在映像中包含秘密加密密钥,这不是我想做的事情吗? c) 是否有一种方式将Cro应用程序放在Apache服务器后面,以便由Apache解密/加密websocket?