【问题标题】:React + Sails + Socket.ioReact + 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

标签: sockets reactjs socket.io sails.js


【解决方案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 中为会话模型进行所需的设置

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 2015-12-21
    • 2018-03-14
    • 2015-11-20
    • 2016-01-20
    • 1970-01-01
    相关资源
    最近更新 更多