【问题标题】:socket io on sails js as API and node+react as FrontendSails js 上的 socket io 作为 API 和 node+react 作为前端
【发布时间】:2017-11-29 15:51:06
【问题描述】:

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

是吗

  1. react 端的 socket.io 客户端连接到其 nodejs 后端上的 socket.io 服务器,该后端连接到 API 上的 socket.io 服务器
  2. react 端的 socket.io 客户端及其连接到 API 上的 socket.io 服务器的 nodejs 后端

我已尝试四处寻找答案,但似乎没有一个符合我的要求。

要尝试一下,我将hello 端点放在我的API 上,使用the sailsjs realtime documentation,但是当我执行sails lift 时出现此错误Could not fetch session, since connecting socket has no cookie (is this a cross-origin socket?) 我想我需要在里面传递一个身份验证代码request headers Authorization 属性。

假设我回答了我的#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.io-client吗?

【问题讨论】:

    标签: node.js reactjs socket.io redux


    【解决方案1】:

    您需要在您的节点服务器上添加sails.io.js。 Sails 套接字行为非常棘手。因为,它没有使用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);
    })
    

    【讨论】:

      猜你喜欢
      • 2014-10-18
      • 2015-03-23
      • 2017-08-07
      • 2015-12-24
      • 2021-07-11
      • 2021-04-29
      • 2018-06-26
      • 2020-10-03
      • 2015-06-14
      相关资源
      最近更新 更多