套接字io在sails js上作为API,节点+作为前端做出反应

时间:2017-06-26 18:07:09

标签: node.js reactjs socket.io redux

我使用sailsjs进行API构建,并将react redux附加到nodejs后端,我正在尝试实现socket.io以进行实时通信,这是如何工作的?

是吗

  1. 反应端的socket.io客户端,连接到nodejs后端的socket.io服务器,连接到API上的socket.io服务器
  2. 反应端的socket.io客户端及其连接到API上的socket.io服务器的nod​​ejs后端
  3. 我试过寻找一些答案,但似乎都没有达到我的要求。

    尝试一下,我使用the sailsjs realtime documentationhello端点放在我的API上,但当我执行sails lift时,我收到此错误Could not fetch session, since connecting socket has no cookie (is this a cross-origin socket?)我认为我需要在request headers Authorization属性中传递一个auth代码。

    假设我去了我的#1问题,并使用redux-socket.io

    在我的redux中间件中,我创建了一个socketMiddleware

    import createSocketIoMiddleware from 'redux-socket.io'
    import io from 'socket.io-client'
    
    import config from '../../../config'
    
    const socket = io(config.host)
    
    export default function socketMiddleware() {
      return createSocketIoMiddleware(
        socket,
        () => next => (action) => {
          const { nextAction, shuttle, ...rest } = action
    
          if (!shuttle) {
            return next(action)
          }
    
          const { socket_url: shuttleUrl = '' } = config
    
          const apiParams = {
            data: shuttle,
            shuttleUrl,
          }
    
          const nextParams = {
            ...rest,
            promise: api => api.post(apiParams),
            nextAction,
          }
    
          return next(nextParams)
        },
      )
    }
    

    和我的redux商店

    import { createStore, applyMiddleware, compose } from 'redux'
    import createSocketIoMiddleware from 'redux-socket.io'
    
    ...
    
    import rootReducers from '../reducer'
    
    
    import socketMiddleware from '../middleware/socketMiddleware'
    import promiseMiddleware from '../middleware/promiseMiddleware'
    ...
    
    import config from '../../../config'
    
    export default function configStore(initialState) {
      const socket = socketMiddleware()
      ...
      const promise = promiseMiddleware(new ApiCall())
    
      const middleware = [
        applyMiddleware(socket),
        ...
        applyMiddleware(promise),
      ]
    
      if (config.env !== 'production') {
        middleware.push(DevTools.instrument())
      }
    
      const createStoreWithMiddleware = compose(...middleware)
      const store = createStoreWithMiddleware(createStore)(rootReducers, initialState)
    
      ...
    
      return store
    }
    

    promiseMiddleware

    export default function promiseMiddleware(api) {
      return () => next => (action) => {
        const { nextAction, promise, type, ...rest } = action
    
        if (!promise) {
          return next(action)
        }
    
        const [REQUEST, SUCCESS, FAILURE] = type
    
        next({ ...rest, type: REQUEST })
    
        function success(res) {
          next({ ...rest, payload: res, type: SUCCESS })
          if (nextAction) {
            nextAction(res)
          }
        }
    
        function error(err) {
          next({ ...rest, payload: err, type: FAILURE })
          if (nextAction) {
            nextAction({}, err)
          }
        }
    
        return promise(api)
          .then(success, error)
          .catch((err) => {
            console.error('ERROR ON THE MIDDLEWARE: ', REQUEST, err) // eslint-disable-line no-console
            next({ ...rest, payload: err, type: FAILURE })
          })
      }
    }
    

    我的ApiCall

    /* eslint-disable camelcase */
    
    import superagent from 'superagent'
    
    ...
    
    const methods = ['get', 'post', 'put', 'patch', 'del']
    
    export default class ApiCall {
      constructor() {
        methods.forEach(method =>
          this[method] = ({ params, data, shuttleUrl, savePath, mediaType, files } = {}) =>
            new Promise((resolve, reject) => {
              const request = superagent[method](shuttleUrl)
    
              if (params) {
                request.query(params)
              }
    
              ...
    
              if (data) {
                request.send(data)
              }
    
              request.end((err, { body } = {}) => err ? reject(body || err) : resolve(body))
            },
        ))
      }
    }
    

    中间件和商店之间的所有这些关系在常规的http api调用中运行良好。我的问题是,我是在正确的道路上吗?如果我,那么我应该在这个reactjs服务器部分写什么来与api socket通信?我还应该使用socket.io-client吗?

1 个答案:

答案 0 :(得分:1)

您需要在节点服务器上添加sails.io.js。套接字套接字的行为非常棘手。因为,它没有使用on方法来监听事件。

创建处理套接字请求的sails端点。文档是here。文件在屁股上是如此痛苦,但请耐心等待。

在节点服务器上。您可以像

一样使用它
import socketIOClient from 'socket.io-client'
import sailsIOClient from 'sails.io.js'

const ioClient = sailsIOClient(socketIOClient)
ioClient.sails.url = "YOUR SOCKET SERVER URL"

ioClient.socket.get("SAILS ENDPOINT WHICH HANDLE SOCKET", function(data) {
  console.log('Socket Data', data);
})