Closed alvaroqt closed 3 years ago
I've created a new server with a new port and it works.... I'm not sure if it's the best way, but it works, any comment will be appreciated.
CLIENT SIDE /src/lib/functions
export function createSocket() {
const serverURL = `http://localhost:4000`;
console.log('connecting socket on: ', serverURL);
return io(serverURL);
}
SERVER SIDE /src/lib/socket
/** SOCKET CONNECTION */
const server = http.createServer();
server.listen(4000);
const sockets = {};
const io = new SocketIO(server);
io.on('connection', socket => {
sockets[socket.id] = socket; // socket table.
socket.emit('action', {type: 'server/HELLO', payload: {message: 'socket connected', code: 1} });
socket.on('action', (action) => {
switch (action.type) {
case 'server/CALL': {
const {source, target, leadId, agentId} = action.payload;
crmami.call(source, target, {
socketId: socket.id,
leadId,
agentId
},
(error) => {
socket.emit('action', {
type: 'server/CALL_FAIL',
payload: { error }
})
});
}
}
});
That's more or less how you'd need to do it in development as you obviously can't occupy browser sync's websocket port.
I've been playing around with this..
The biggest problem I can see is dealing with auth. you could use something like socket-jwt-auth
but that relies on passing the jwt as a query string. Alternatively you can implement some sort of authentication exchange after a socket connects like this
I also had trouble with the server reloading, like at first glance I can't see how react-starter-kit decides what to kill when you save a file, so on every reload my src/server
tries to spawn another socket server but collides with the previous one still listening on that port.
@leviwheatcroft is right, my solution fails on reload, please HELP.
Hello I made a little change on start and It seams to work... can anybody verify if this is OK? ... I did it from my ignorance...
/tools/start.js
function checkForUpdate(fromUpdate) {
const hmrPrefix = '[\x1b[35mHMR\x1b[0m] ';
if (!app.hot) {
throw new Error(`${hmrPrefix}Hot Module Replacement is disabled.`);
}
if (app.hot.status() !== 'idle') {
return Promise.resolve();
}
return app.hot
.check(true)
.then(updatedModules => {
if (!updatedModules) {
if (fromUpdate) {
console.info(`${hmrPrefix}Update applied.`);
}
return;
}
if (updatedModules.length === 0) {
console.info(`${hmrPrefix}Nothing hot updated.`);
} else {
console.info(`${hmrPrefix}Updated modules:`);
updatedModules.forEach(moduleId =>
console.info(`${hmrPrefix} - ${moduleId}`),
);
checkForUpdate(true);
}
})
.catch(error => {
if (['abort', 'fail'].includes(app.hot.status())) {
console.warn(`${hmrPrefix}Cannot apply update.`);
delete require.cache[require.resolve('../build/server')];
// eslint-disable-next-line global-require, import/no-unresolved
app.server.removeListener('./router'); /* <--- this is the line to FIX de problem */
app = require('../build/server').default;
console.warn(`${hmrPrefix}App has been reloaded.`);
} else {
console.warn(
`${hmrPrefix}Update failed: ${error.stack || error.message}`,
);
}
});
}
@alvaroqt in case you missed it, or for anyone else looking at this, the apollo branch recently updated from apollo-client 1.x to 2.x. I haven't really dug into it but I'm pretty sure this provides access to some fancy new features which might be a convenient substitute for socket.io functionality.
Is this socket server intended for graphql subscriptions or something else?
@leviwheatcroft Yes, I updated apollo branch, but it still uses plain old original GraphQL server and not introduces subscriptions nor websockets. It can be easy to do but I doubt that it can decay quickly, so I don't want to dig into in near future.. This is task for current—future—open—source—CMS which I can start, but nobody will give single $
for my living needs :slightly_frowning_face:
Integration of real-time features can be blazingly easy in GraphQL, but sometimes you want simples working solution, so @alvaroqt look at faye-websocket
Are subscriptions/redis something you'd want the Apollo branch to have?
@tim-soft Hmm.. I think that this is out of scope of Apollo branch, but can be in scope of feature/apollo-realtime
branch which isn't exist yet :slightly_smiling_face:
Hypothetically speaking, I'd try to make a socket.js
file under src
, add a socket section in the webpack config and then mimic the server creation steps in /tools/start.js
for the socket server. The socket should be it's own entity just like the current server and in a production build, be separable so you could slap it on it's own machine. Then adding in the ws apollo link is pretty self explanatory
My app uses socket.io to map events from a callcenter server and realtime live call events, untill now my solution is working OK, i don't understand if GraphQL or Apollo can help with this in any way. My app is connected with the callcenter server throught some kind of terminal connection using a node-express module, then receive and send events to the front end using socket.io.
@alvaroqt Apollo implements the GraphQL spec including the experimental Subscriptions type. Unlike queries and mutations, subscriptions need a websocket server and some sort of pub-sub system like Redis in order to work.
In your scenario, you'd need to emit a subscription to a channel containing a payload object describing what has changed. You could think of this like sending a message to a group in Slack.
react-apollo
lets you subscribe
to a channel, allowing your react components to receive these messages(object payloads). When your UI receives a payload, you typically update the Apollo Cache, which will automagically update your UI that is using that data from the cache.
You could make it work but in order to use GraphQL subscriptions via Apollo, you'll need to incorporate redis and ws somewhere, they don't necessarily need to exist inside rsk, but they can.
@tim-soft I don't think that GraphQL subscriptions will be most fit for @alvaroqt's use case — signaling VoIP or similar.. May be it can, but plain WebSocket + Redis can be simpler, more flexible and overall better fit I think..
To each their own, I've drank the subscriptions kool-aid at this point. @alvaroqt Good luck!
edit: you can try it this way https://github.com/tgdn/react-starter-kit-subscription
@alvaroqt, Hey you can integrate Socket IO server for prod build by replacing this code in src/server.js
if (!module.hot) {
promise.then(() => {
app.listen(config.port, () => {
console.info(`The server is running at http://localhost:${config.port}/`);
});
});
}
with this
if (!module.hot) {
promise.then(() => {
const mainServer = app.listen(config.port, () => {
console.info(`The server is running at http://localhost:${config.port}/`);
});
const io = require('socket.io').listen(mainServer);
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
});
}
@alvaroqt thank you very much for crating this issue! Unfortunately, we have close it due to inactivity. Feel free to re-open it or join our Discord channel for discussion.
NOTE: The main
branch has been updated with React Starter Kit v2, using JAM-style architecture.
Hello, I can't find the way to establish a communication with a socket.io port... it works on the build but i have some kind of conflict with Browser-sync, i tried different configurations, but it doesn't establish the connection. In some cases i receive a 404 error page from express.
Here is the code, please help me on how to revolve this issue or how te remove or deactivate browser-sync, is not critic for my project. But when i tried to remove the dev version stop to works, I don't know how to replace Browser-sync, to keep the dev environment with HMR operational.
Please I'll appreciate any orientation, I've invested a lot of time in this issue and it surpasses me.
CLIENT SIDE // /src/store/configureStore.js
/src/lib/functions.js
SERVER SIDE /src/server.js
/src/lib/socket
/tools/start.js