是否可以使用带有 websockets 的 web 服务器作为另一个服务器的包装器,将消息从“真实服务器”传递到 web 客户端并返回?
我对此感到好奇,因为我有一个用 Ada 编写的游戏服务器,它有一个与操作系统相关的客户端。我想把这个客户端换成一个基于Javascript的webclient,这样游戏就可以在普通浏览器中玩了。可以做什么?
这就是websockify的目的。它旨在桥接 WebSocket 客户端和常规 TCP 服务器。它是作为 noVNC 的一部分创建的,noVNC是一个可以连接到普通 VNC 服务器的 HTML5 VNC 应用程序。但是,websockify 是通用的,现在有许多其他项目在使用它。
免责声明:我创建了 websockify 和 noVNC。
您可以使用 AWS 轻松完成此操作:
http://libre.adacore.com/tools/aws/
AWS 中支持 websocket,您可以利用它的优秀套接字 (AWS.Net) 包来支持普通套接字。
Kaazing HTML5 网关是将基于 TCP 的协议引入 Web 客户端的好方法。Kaazing 网关基本上将您的协议运行在 TCP 之上并将其转换为 WebSocket,以便您可以访问客户端中的协议。您仍然需要为后端使用的协议编写一个 JavaScript 协议库。但是,如果您可以在 TCP 之上使用该协议,那么使用 JavaScript 并不难。
与某些人认为的相反,Websocket 不是纯套接字。原始数据由尚未广泛支持的 websocket 协议封装和屏蔽。这意味着不是为它设计的应用程序,您不能直接通过 Web 套接字与其通信。
当您有一个使用基于普通套接字的协议的应用程序,并且您想通过 websockets 与它通信时,有两种选择。
您要么使用 websocket 网关,它对 websocket 流量进行解包/打包,并将其作为纯套接字流量转发给应用程序。这样做的好处是您不需要修改应用程序,但它的缺点是它还掩盖了客户端的真实 IP 地址,这对于某些应用程序可能是也可能不是问题。
或者你直接在你的应用程序中实现 websocket。这可以通过让服务器监听两个不同的端口来完成,一个用于正常连接,一个用于 websocket 连接。通过 websocket-port 接收或发送的任何数据在发送之前/接收之后通过您的 websocket 实现发送,否则由相同的例程处理。
我在 ruby 中使用以下代码来包装我的套接字。该代码改编自em-websocket-proxy。我的项目可能有一些细节,但通常切换 remote_host 和 remote_port 并连接到 localhost:3000 应该为您设置一个通过 websocket 与您的服务器的新连接。
require 'rubygems'
require 'em-websocket'
require 'sinatra/base'
require 'thin'
require 'haml'
require 'socket'
class App < Sinatra::Base
get '/' do
haml :index
end
end
class ServerConnection < EventMachine::Connection
def initialize(input, output)
super
@input = input
@output = output
@input_sid = @input.subscribe { |msg| send_data msg+ "\n" }
end
def receive_data(msg)
@output.push(msg)
end
def unbind
@input.unsubscribe(@input_sid)
end
end
# Configuration of server
options = {:remote_host => 'your-server', :remote_port => 4000}
EventMachine.run do
EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |ws|
ws.onopen {
output = EM::Channel.new
input = EM::Channel.new
output_sid = output.subscribe { |msg| ws.send msg; }
EventMachine::connect options[:remote_host], options[:remote_port], ServerConnection, input, output
ws.onmessage { |msg| input.push(msg)}
ws.onclose {
output.unsubscribe(output_sid)
}
}
end
App.run!({:port => 3000})
end
享受!并询问您是否有问题。