【发布时间】:2017-04-18 09:51:01
【问题描述】:
我正在运行一个 SailsJS 实例 (v0.12.3),我有一个控制器 MyModelController 处理 WebSocket (socket.io) 连接,如果用户允许该连接已通过身份验证。
MyModelController
module.exports = {
/**
* Socket connection
*/
connect: function(req, res) {
/* Checks it's a socket connection request */
if (!req.isSocket) { return res.badRequest();}
/* Checks it's authenticated */
if (req.session.me) {
User.findOne(req.session.me, function (err, me) {
if (req.param('name')) {
MyModel.findOne({
name: req.param('name')
}).exec(function(err, objectFound) {
/* e.g. Join a room named after the params passed */
sails.sockets.join(req, objectFound.name);
return res.ok({ message: "All is OK!"}});
});
}
});
}
}
}
来自 SailsJS 提供的页面,例如myPage.ejs,这很好用:
<!DOCTYPE html>
<html>
<head>...</head>
<body>
...
<script src="/js/dependencies/sails.io.js"></script>
<script src="/js/dependencies/app.io.js"></script>
<script src="/vendor/jquery/jquery.min.js"></script>
<script type "text/javascript">
// Use .get() to contact the server
io.socket.get('/myModel/connect?name=john', function gotResponse(body, response) {
console.log('Status code ' + response.statusCode + ' & data: ', body);
});
</script>
</body>
</html>
如何从 Python 客户端连接到 SailsJS socket.io 服务器?
在最初的几次尝试中,我尝试将身份验证部分留到以后。因此,假设我们现在不必担心它。
我安装了一个 Python socket.io 客户端pip install socketIO-client-2 见socketIO-client-2 doc。
对于初学者来说,尝试过这个(哦,顺便说一句,我正在使用带有自签名证书的安全连接):
from socketIO_client import SocketIO
SocketIO('https://localhost:1337/myModel/connect', params={'name': 'john'}, verify=False)
但随后我在 Sails 服务器端立即收到错误消息:
verbose: Sending 400 ("Bad Request") response
客户端出错
Failed to establish a new connection: [Errno 61] Connection refused
所以我把socket连接请求和认证检查都注释掉了,为了更简单,希望能搞清楚……
connect: function(req, res) {
if (req.param('name')) {
MyModel.findOne({
name: req.param('name')
}).exec(function(err, objectFound) {
console.log(req.socket.id);
console.log(param('name'));
sails.sockets.join(req, objectFound.name);
return res.ok({ message: "All is OK!"}});
});
} else {
console.log('No params passed to the websocket');
}
}
这给了我在风帆方面:
connect > found object: { name: 'john',
id: 1,
createdAt: '2016-11-04T15:20:38.000Z',
updatedAt: '2016-11-04T15:20:38.000Z' }
Socket request undefined <============== UNDEFINED
warn: Attempted to call `sailsSockets.join`, but the first argument was not a socket.
Socket Id: undefined
我的 Python 日志:
/usr/local/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:843: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
Traceback (most recent call last):
File "wsclient.py", line 17, in <module>
SocketIO('https://localhost:1337/myModel/connect', params={'name': 'john'}, verify=False)
File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 334, in __init__
resource, hurry_interval_in_seconds, **kw)
File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 51, in __init__
self._transport
File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 59, in _transport
self._engineIO_session = self._get_engineIO_session()
File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 73, in _get_engineIO_session
transport.recv_packet())
File "/usr/local/lib/python2.7/site-packages/socketIO_client/transports.py", line 81, in recv_packet
for engineIO_packet in decode_engineIO_content(response.content):
File "/usr/local/lib/python2.7/site-packages/socketIO_client/parsers.py", line 95, in decode_engineIO_content
content, content_index)
File "/usr/local/lib/python2.7/site-packages/socketIO_client/parsers.py", line 202, in _read_packet_length
while get_byte(content, content_index) not in [0, 1]:
File "/usr/local/lib/python2.7/site-packages/socketIO_client/symmetries.py", line 28, in get_byte
return six.indexbytes(x, index)
File "/usr/local/lib/python2.7/site-packages/six.py", line 655, in indexbytes
return ord(buf[i])
IndexError: string index out of range
任何指针?
有趣的链接:
当 NodeJS +sails.io.js
我想我想实现这个,但是在 python 中
var socketIOClient = require('socket.io-client');
var sailsIOClient = require('sails.io.js');
// Instantiate the socket client (`io`)
// (for now, you must explicitly pass in the socket.io client when using this library from Node.js)
var io = sailsIOClient(socketIOClient);
// Set some options:
// (you have to specify the host and port of the Sails backend when using this library from Node.js)
io.sails.url = 'http://localhost:1337';
// ...
// Send a GET request to `http://localhost:1337/hello`:
io.socket.get('/hello', function serverResponded (body, JWR) {
// body === JWR.body
console.log('Sails responded with: ', body);
console.log('with headers: ', JWR.headers);
console.log('and with status code: ', JWR.statusCode);
// When you are finished with `io.socket`, or any other sockets you connect manually,
// you should make sure and disconnect them, e.g.:
io.socket.disconnect();
// (note that there is no callback argument to the `.disconnect` method)
});
连接时会给出这个日志
$ DEBUG=* node sio-client.js
socket.io-client:url parse https://localhost:1337 +0ms
socket.io-client new io instance for https://localhost:1337 +5ms
socket.io-client:manager readyState closed +3ms
socket.io-client:manager opening https://localhost:1337 +0ms
engine.io-client:socket creating transport "websocket" +1ms
engine.io-client:socket setting transport websocket +29ms
socket.io-client:manager connect attempt will timeout after 20000 +0ms
socket.io-client:manager readyState opening +7ms
engine.io-client:socket socket receive: type "open", data "{"sid":"hj4FCwhk_pQ3hoTbAAAE","upgrades":[],"pingInterval":25000,"pingTimeout":60000}" +17ms
engine.io-client:socket socket open +0ms
socket.io-client:manager open +0ms
socket.io-client:manager cleanup +1ms
socket.io-client:socket transport is open - connecting +0ms
engine.io-client:socket socket receive: type "message", data "0" +215ms
socket.io-parser decoded 0 as {"type":0,"nsp":"/"} +0ms
socket.io-client:socket emitting packet with ack id 0 +3ms
socket.io-client:manager writing packet {"type":2,"data":["get",{"method":"get","headers":{},"data":{},"url":"/mymodel/connect?name=john"}],"options":{"compress":true},"id":0,"nsp":"/"} +0ms
socket.io-parser encoding packet {"type":2,"data":["get",{"method":"get","headers":{},"data":{},"url":"/mymodel/connect?name=john"}],"options":{"compress":true},"id":0,"nsp":"/"} +2ms
socket.io-parser encoded {"type":2,"data":["get",{"method":"get","headers":{},"data":{},"url":"/mymodel/connect?name=john"}],"options":{"compress":true},"id":0,"nsp":"/"} as 20["get",{"method":"get","headers":{},"data":{},"url":"/mymodel/connect?name=john"}] +0ms
engine.io-client:socket flushing 1 packets in socket +1ms
|> Now connected to Sails.
\___/ For help, see: http:
(using sails.io.js node SDK @v1.1.0)
engine.io-client:socket socket receive: type "message", data "30[{"body":{"mymodel":{"name":"john","id":1,"createdAt":"2016-11-04T15:20:38.000Z","updatedAt":"2016-11-04T15:20:38.000Z","assembly":"drive"},"message":"DRIVE, Joined room john"},"headers":{"Access-Control-Allow-Origin":"","Access-Control-Allow-Credentials":"","Access-Control-Allow-Methods":"","Access-Control-Allow-Headers":"","Access-Control-Expose-Headers":"","access-control-allow-origin":"","access-control-allow-credentials":"","access-control-allow-methods":"","access-control-allow-headers":"","access-control-expose-headers":""},"statusCode":200}]" +242ms
socket.io-parser decoded 30[{"body":{"mymodel":{"name":"john","id":1,"createdAt":"2016-11-04T15:20:38.000Z","updatedAt":"2016-11-04T15:20:38.000Z","assembly":"drive"},"message":"DRIVE, Joined room john"},"headers":{"Access-Control-Allow-Origin":"","Access-Control-Allow-Credentials":"","Access-Control-Allow-Methods":"","Access-Control-Allow-Headers":"","Access-Control-Expose-Headers":"","access-control-allow-origin":"","access-control-allow-credentials":"","access-control-allow-methods":"","access-control-allow-headers":"","access-control-expose-headers":""},"statusCode":200}] as {"type":3,"nsp":"/","id":0,"data":[{"body":{"mymodel":{"name":"john","id":1,"createdAt":"2016-11-04T15:20:38.000Z","updatedAt":"2016-11-04T15:20:38.000Z","assembly":"drive"},"message":"DRIVE, Joined room john"},"headers":{"Access-Control-Allow-Origin":"","Access-Control-Allow-Credentials":"","Access-Control-Allow-Methods":"","Access-Control-Allow-Headers":"","Access-Control-Expose-Headers":"","access-control-allow-origin":"","access-control-allow-credentials":"","access-control-allow-methods":"","access-control-allow-headers":"","access-control-expose-headers":""},"statusCode":200}]} +244ms
socket.io-client:socket calling ack 0 with [{"body":{"mymodel":{"name":"john","id":1,"createdAt":"2016-11-04T15:20:38.000Z","updatedAt":"2016-11-04T15:20:38.000Z","assembly":"drive"},"message":"DRIVE, Joined room john"},"headers":{"Access-Control-Allow-Origin":"","Access-Control-Allow-Credentials":"","Access-Control-Allow-Methods":"","Access-Control-Allow-Headers":"","Access-Control-Expose-Headers":"","access-control-allow-origin":"","access-control-allow-credentials":"","access-control-allow-methods":"","access-control-allow-headers":"","access-control-expose-headers":""},"statusCode":200}] +1ms
hello again
Sails responded with: { mymodel:
{ name: 'john',
id: 1,
createdAt: '2016-11-04T15:20:38.000Z',
updatedAt: '2016-11-04T15:20:38.000Z',
assembly: 'drive' },
message: 'DRIVE, Joined room john' }
with headers: { 'Access-Control-Allow-Origin': '',
'Access-Control-Allow-Credentials': '',
'Access-Control-Allow-Methods': '',
'Access-Control-Allow-Headers': '',
'Access-Control-Expose-Headers': '',
'access-control-allow-origin': '',
'access-control-allow-credentials': '',
'access-control-allow-methods': '',
'access-control-allow-headers': '',
'access-control-expose-headers': '' }
and with status code: 200
注意它正在写数据包
{
"type":2,
"data":[
"get",
{
"method":"get",
"headers":{},
"data":{},
"url":"/myModel/connect?name=john"
}
],
"options":{
"compress":true
},
"id":0,
"nsp":"/"
}
尝试副作用的建议
这是我正在运行的代码pastebin
在风帆一侧
verbose: Could not fetch session, since connecting socket has no cookie (is this a cross-origin socket?)
Generated a one-time-use cookie:sails.sid=s%3AR-Sm_JeWKoqayZOku-EvxPR_uUpilwVU.3yRUVjmYSpCl%2BeT4sJIOH%2BUTOL3EjWFabDKbswSlkdIand saved it on the socket handshake.
This will start this socket off with an empty session, i.e. (req.session === {})
That "anonymous" section will only last until the socket is disconnected unless you persist the session id in your database,
or by setting the set-cookie response header for an HTTP request that you *know* came from the same user (etc)
Alternatively, just make sure the socket sends a `cookie` header or query param when it initially connects.
关于 socket.io python 客户端的调试信息:
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:334: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
SNIMissingWarning
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:132: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecurePlatformWarning
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py:843: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
DEBUG:root:192.168.178.20:1337/socket.io [transport selected] websocket
DEBUG:root:192.168.178.20:1337/socket.io [heartbeat reset]
DEBUG:root:192.168.178.20:1337/socket.io [socket.io packet sent] 21["get", {"url": "/path/connect", "headers": {}, "data": {"name": "john"}, "method": "get"}]
DEBUG:root:192.168.178.20:1337/socket.io [socket.io packet received] 0
【问题讨论】:
-
这可能是一个愚蠢的问题,但你为什么使用 python 客户端?
-
不是一个愚蠢的问题,我基本上别无选择,否则我会选择 nodejs 客户端。我只需要将这个功能(与 Sails 的连接)包含到用 Python 编写的大量遗留软件中。其中一个 python 模块处理需要发送到 Sails 实例的数据。后者以一种非常特殊的方式实现 socket.io,我承认,我还没有完全掌握。我现在非常绝望。我想我可以创建一个 nodejs 套接字服务器,它可以使用 Sails.io.js 将消息从 Python 堆栈中继到 Sails ......不要太兴奋。有什么想法吗?
标签: python node.js socket.io sails.js