React + Sails + Socket.io
Posted
技术标签:
【中文标题】React + Sails + Socket.io【英文标题】: 【发布时间】:2017-01-16 20:58:12 【问题描述】:这是一个相当广泛的问题,但是我目前有一个 Sails API 服务器和一个 React 前端(独立)。
注意:React 前端不是 Sails 的一部分
我正在尝试掌握套接字,所以我想我会从简单的开始。我想实现以下目标:
用户访问我的网站 (React) React 打开一个套接字并连接到 Sails Sails 从函数/模型中流式传输数据 将新数据添加到模型时响应更新我半理解使用 Express 和 React 是如何工作的,但是我无法理解 Sails 如何在 Sockets.io 之上实现他们的 WebSockets 版本。
我所做的是在 React 中安装 sockets.io-client,然后尝试在 Sails 中使用sails.sockets。
这是我目前拥有的:
React 组件 注意:我认为这根本不正确
componentDidMount =()=>
this.getSessionData();
UserStore.listen(this.getSessionData);
Socket.emit('/listSessions', function(data)
console.log(data);
)
Sails 函数 (listSessions)
listSessions: function(req, res)
Session.find( where: visible: true, sort: 'createdAt DESC',
function(err, sessions)
if(req.isSocket)
Session.watch(req.socket);
console.log('User subscribed to ' + req.socket.id);
if(err) return res.json(500,
error: err,
message: 'Something went wrong when finding trades'
);
return res.json(200,
sessions: sessions,
);
)
,
Sails Function(createSession)在上面的函数中尝试使用publishCreate与Session.watch配合使用
createSession: function(req, res)
var token = jwt.sign(
expiresIn: 30,
, 'overwatch');
Session.create(
username: req.body.username,
platform: req.body.platform,
lookingFor: req.body.lookingFor,
microphone: req.body.microphone,
gameMode: req.body.gameMode,
comments: req.body.comments,
avatar: null,
level: null,
hash: token,
competitiveRank: null,
region: req.body.region,
visible: true,
).exec(function(err, created)
Session.publishCreate(created);
if(err)
console.log(err);
return res.send(
error: err,
message: 'Something went wrong when adding a session',
code: 91
)
if(req.isSocket)
Session.watch(req.socket);
console.log('User subscribed to ' + req.socket.id);
return res.send(
session: created,
code: 00,
)
);
,
这两个 Sails 函数都是使用 POST/GET 调用的。 我完全不知道该去哪里,而且关于如何使其工作的文档或解释似乎是有限的。所有关于 Sockets 的 Sails 文档似乎都与使用 Sails 作为前端和服务器有关
【问题讨论】:
我以后可能会给出一个更充实的答案,但你很容易发现混淆。在您的客户端中,您将回调函数传递给socket.emit
。这是不正确的。当您 EMIT 时,您传递数据(或 null 或其他)。当你想接收数据时,它是一个 ON 处理程序socket.on('someServerEvent', function (data) ...
谢谢,但是我想做的是在 Sails 的 listSession 函数上执行帖子
好吧,那不是这样的。尽管sails 可能包含一些内置的socket 东西给你,但没有什么能阻止你添加socket.io 服务器端包并在那里监听事件,传递你需要的任何模型数据。套接字是基于命名事件的事件,这些事件不同于用于 HTTP 调用的路由。
是的,我认为这不是它的工作原理,但是我什至无法弄清楚如何让 Sails 函数将数据发送到连接。根据文档,publishCreate 和 Watch 一起工作,但正如您在我的代码中看到的,我需要先将初始数据获取到 React
【参考方案1】:
好的,所以我设法解决了这个问题:
简单地说:
在 React 中,我必须包含 https://github.com/balderdashy/sails.io.js/tree/master
然后在我的 React 组件中我做了:
componentDidMount =()=>
io.socket.get('/listSessions',(resData, jwres) =>
console.log('test');
this.setState(
sessions: resData.sessions,
loaded: true,
)
)
io.socket.on('session', (event) =>
if(event.verb == 'created')
let sessions = this.state.sessions;
sessions.push(event.data);
this.setState(
sessions: sessions
)
else
console.log('nah');
);
这会使用 Socket.io 向 Sails 发出虚拟获取请求,并将响应设置为状态。它还监视“会话”连接的更新并使用这些更新更新状态,这意味着我可以实时更新列表
在我的 Sails 控制器中,我有:
listSessions: function(req, res)
if(req.isSocket)
Session.find( where: visible: true, sort: 'createdAt DESC',
function(err, sessions)
Session.watch(req.socket);
if(err) return res.json(500,
error: err,
message: 'Something went wrong when finding trades'
);
return res.json(200,
sessions: sessions,
);
)
,
Session.watch 行通过 publishCreate 在我的模型中找到的模型上侦听更新,如下所示:
afterCreate: function(message, next)
Session.publishCreate(message);
next();
,
【讨论】:
你是如何整合风帆和反应的?你知道任何文学作品吗?【参考方案2】:添加@K20GH 的回答,将以下内容添加到我在 React 中的“index.js”中,以帮助从 CDN 获取sails.io.js:
const fetchJsFromCDN = (src, externals = []) =>
return new Promise((resolve, reject) =>
const script = document.createElement('script');
script.setAttribute('src', src);
script.addEventListener('load', () =>
resolve(
externals.map(key =>
const ext = window[key];
typeof ext === 'undefined' &&
console.warn(`No external named '$key' in window`);
return ext;
)
);
);
script.addEventListener('error', reject);
document.body.appendChild(script);
);
;
fetchJsFromCDN(
'https://cdnjs.cloudflare.com/ajax/libs/sails.io.js/1.0.1/sails.io.min.js',
['io']
).then(([io]) =>
if (process.env.NODE_ENV === 'development')
io.sails.url = 'http://localhost:1337';
);
一旦你有了这个,你就可以使用 HTTP 类型的 GET、PUT、POST 和 DELETE 方法。所以在这里你可以这样做:
componentDidMount =()=>
io.socket.get('/listSessions',(resData, jwres) =>
console.log('test');
this.setState(
sessions: resData.sessions,
loaded: true,
)
)
io.socket.on('session', (event) =>
if(event.verb == 'created')
let sessions = this.state.sessions;
sessions.push(event.data);
this.setState(
sessions: sessions
)
else
console.log('Not created session');
);
您可以按照上面的建议在sails 中为会话模型进行所需的设置
【讨论】:
以上是关于React + Sails + Socket.io的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中创建 Socket.io 客户端以与 Sails 服务器通信