【发布时间】:2017-11-29 15:51:06
【问题描述】:
我有一个使用sailsjs 的 API 构建和一个附加到 nodejs 后端的 react redux,我正在尝试实现 socket.io 进行实时通信,这是如何工作的?
是吗
- react 端的 socket.io 客户端连接到其 nodejs 后端上的 socket.io 服务器,该后端连接到 API 上的 socket.io 服务器
- 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