用Python编写代码,在Node.js和Socket.IO中进行通信,以HTML显示
您有一个python脚本用Python编写代码,在Node.js和Socket.IO中进行通信,以HTML显示,python,html,node.js,socket.io,Python,Html,Node.js,Socket.io,您有一个python脚本diagnosis.py,它生成基于事件的实时数据。使用Node.js,您可以将其作为子进程启动并捕获其输出,然后使用Socket.IO将其发送给客户端,并使用HTML呈现 服务器 var util = require('util'), spawn = require('child_process').spawn, ls = spawn('python', ['diagnosis.py']); var app = require('http').
diagnosis.py
,它生成基于事件的实时数据。使用Node.js,您可以将其作为子进程启动并捕获其输出,然后使用Socket.IO将其发送给客户端,并使用HTML呈现
服务器
var util = require('util'),
spawn = require('child_process').spawn,
ls = spawn('python', ['diagnosis.py']);
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
ls.stdout.on('data', function (gdata) {
socket.emit('news', gdata.toString());
});
});
var socket = io.connect('http://localhost/gaze');
socket.on('gaze', function (data) {
console.log(data);
});
客户端
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
var d = "";
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
d += data;
document.getElementById('data').innerHTML = d;
console.log(data);
});
</script>
</head>
<body>
<div id="data"></div>
</body>
</html>
var d=“”;
var socket=io.connect('http://localhost');
socket.on('news',函数(数据){
d+=数据;
document.getElementById('data').innerHTML=d;
控制台日志(数据);
});
问题
self.mainSocket = SocketIO('localhost', 80)
self.gazeSocket = self.mainSocket.connect('/gaze')
self.gazeSocket.emit('gaze', ...)
这很好,但如果您正在寻找Socket.IO提供的相同HTML-Node.js通信能力,而不是Node.js和Python之间的通信能力,该怎么办?你会怎么做?那里没有web服务器,因此Socket.IO没有多大意义,通过裸TCP进行通信也不能提供同样的功能/优雅。如何在Node.js和Python之间实现全双工通信
更新我回答了自己的问题,但我愿意接受另一种方法。不过,RPC并没有达到我想要的效果。是在所有主要语言之间编写RPC代码的一种非常棒的方法。编写一个通用Thrift规范,声明类型和服务,然后代码生成器为所需语言创建绑定。可以使用API在节点和python代码库之间调用方法
在更通用的低级方法中,是一个消息队列库,它还支持所有主要语言。有了它,您可以设计自己的通信解决方案(不仅仅是RPC)。它有请求/回复、推/拉、发布/订阅和配对模式。它为您提供了足够的工具来组装任何类型的可伸缩系统
我使用了这两种方法,它们都是很好的解决方案
作为一个非常粗略的例子,节俭规范可能是这样的。假设您希望将事件从python传递到node.js,对其进行处理并获得一些响应:
节约
这定义了一个名为Event
的数据结构,其中包含一个字符串成员来保存消息。然后,一个名为RpcService
的服务定义一个名为eventoccurrend
的函数,该函数需要一个事件作为参数,并将返回一个字符串
为python和node.js生成此代码时,可以使用python的客户端代码和node.js的服务器端代码
蟒蛇
node.js
如果您只是想在套接字之上找到一个简单的协议,那么您可以查看一些消息传递系统,如0mq,这样您就不必处理缓冲和分隔消息以及所有这些事情,两个明显的选择(取决于您尝试发送的数据类型)是NetString和JSON-RPC。对于这两种语言,都有多种库可供选择,但您最终可以得到如下简单的代码:
class MyService(Service):
# … code to set up the newsdb
def getnews(self, category, item):
return self.newsdb.get(category, item)
myService = MyService(6000)
myService = Service(6000)
// … code to set up the newsdb
myService.getnews = function(category, item, callback) {
callback(this.newsdb.get(category, item);
}
我使用受此启发的库将diagnosis.py
转换为Socket.IO客户端。这样,我可以将实时数据发送到Node.js Socket.IO服务器:
socketIO.emit('gaze', ...)
然后让它执行一个socket.broadcast.emit
,将数据发送到所有socket.IO客户端(浏览器和diagnosis.py
)
RPC可能是跨语言开发的更标准的方法,但我发现当目标是交换数据时,这样做有点过分。它也不支持开箱即用的事件IO
2013年1月更新由于socket.broadcast.emit
产生了大量不必要的流量,我试图找到一种更好的方法来实现这一点。我提出的解决方案是使用名称空间,这是我提到的基本pythonsocket.IO客户端库所支持的
Python
self.mainSocket = SocketIO('localhost', 80)
self.gazeSocket = self.mainSocket.connect('/gaze')
self.gazeSocket.emit('gaze', ...)
连接到名称空间
Node.js
var gaze = io.of('/gaze').on('connection', function (socket) {
socket.on('gaze', function (gdata) {
gaze.emit('gaze', gdata.toString());
});
});
这将仅向连接到名称空间的客户端发送接收到的数据
浏览器
var util = require('util'),
spawn = require('child_process').spawn,
ls = spawn('python', ['diagnosis.py']);
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
ls.stdout.on('data', function (gdata) {
socket.emit('news', gdata.toString());
});
});
var socket = io.connect('http://localhost/gaze');
socket.on('gaze', function (data) {
console.log(data);
});
如果这就是您要做的,为什么不直接使用python呢?和/或可能有助于我同意@JonasWielicki。这就是你的node.js所做的,还是这只是这个问题的一个简化示例?好吧,他想在浏览器端使用WebSocket,所以SimpleHTTPServer
和/或WSGI
不会有帮助。但是威尔。@abarnert:OP实际上特别想要socket.io。但是也有针对python的socket.io解决方案,这意味着如果需要,整个服务器都可以使用python。我认为问题的根源其实只是关于是否只为示例中列出的简单目的使用node.js,以及是否需要node和python之间的通信层。但是我想答案是,你在node.js上做的事情比这里列出的要多得多。但是它支持基于事件的实时通信吗?我是否可以从Python服务器发出数据,并在发出数据时在Node.js客户机上执行某些操作?如果您这样使用它,它是基于事件的。例如,Thrift将为您提供两个系统之间的方法调用。假设您编写了一个名为eventoccurrend(event)
的储蓄服务。当您的事件发生在python端时,您只需使用事件对象调用eventoccurrend()
,然后node.js端将接收该调用,就好像它是本地的一样,并可以根据需要发送返回值(如果它是在thrift规范中设置的,则返回结果)。使用thrift,您只需定义特定服务的处理程序。在node.js中,这基本上是每个服务的回调。