socket.io-client keeping on connecting when using in react-native - websocket

I want to use the websocket in my RN project. And I did it using the ws at server side and the RN built-in websocket implementation.
But it seems not so convinient since I use socket.io before.
So I tried to use socket.io:
In RN:
import './userAgent'
import io from "socket.io-client/socket.io"
In component:
componentDidMount() {
this.socket = io('https://localhost:4080',{jsonp: false});
this.socket.on('hello', (msg) =>{
this.setState({response:msg})
});
}
In the server:
io.on('connection', function(socket){
socket.emit('hello','hello world')
console.log('a user connected');
socket.on('disconnect',function(){
console.log('user disconnected')
})
})
And in userAgent.js
window.navigator.userAgent = 'react-native';
That is just the result I googled and they said it will work. But for me, the chrome debugger stopped at:
function load() {
var r;
try {
r = exports.storage.debug;
} catch(e) {}
return r;
}
And it says the storage is not defined.
Then I looked into the socket.io.js and find that the exports.storage is window.localStorage. So I disabled the remote js debug, and the code began running.
But the server continues to log : a user connected . as if my RN app is keeping on connecting to the server. And it seems the socket.on() did not work at client side.
react-native version:0.27.2
socket.io-client version:1.4.8
Anyone knows where is going wrong?

Well,finally I found the solution after looking through the socket.io source.
It seems that the socket.io does not use 'websocket' as transport defaultly. It will use the 'polling' in my case, so just explicityly set it :
componentDidMount() {
var socket = io('http://localhost:4080', { jsonp: false, transports: ['websocket'] })
socket.on('hello', (msg) => {
//do something
});
}
Now it works.
But what still confuses me is that in brower client I do not set the transports and it just work well but in react-native it doesn't. Not figured out why.

Related

Svelte/Sveltekit and socket.io-client not working in dev (works in preview)

I'm trying to make socket.io-client work in a svelte front end app to talk to an existing API server that already uses socket.io. After a number of challenges, I managed to make this work but I can only get this to work with sveltekit's preview and not in dev mode. Wondered if someone with some knowledge of those could explain why or suggest what I need to do to get it connecting in dev?
svelte 3.34.0
sveltekit next-169
socket.io(-client) 4.2.0
basic code as follows, currently within a file $lib/db.js where I define a few stores that are pulled into the layout for general use..
import { io } from "socket.io-client";
import { browser } from '$app/env';
const initSocket = async () => {
console.log('creating socket...');
let socket = io('http://192.168.1.5:4000', { 'connect timeout': 5000 });
socket.on("connect", () => {
// always works in preview...
console.log('socket created with ID:', socket.id);
});
socket.on("connect_error", (error) => {
// permanently fired in dev...
console.error('Failed to connect', error);
});
socket.on("error", (error) => {
console.error('Error on socket', error);
});
socket.on("foo", data => {
// works in preview when server emits a message of type 'foo'..
console.log("FOO:", data);
});
};
if (browser) {
initSocket();
}
// stores setup and exports omitted..
with svelte-kit preview --host I see the socket creation log message with the socket ID and the same can be seen on the api server where it logs the same ID. The socket works and data is received as expected.
with svelte-kit dev --host however, the log message from socket.on("connect").. is never output and I just see an endless stream of error messages in the browser console from the socket.on("connect_error").. call..
Failed to connect Error: xhr poll error
at XHR.onError (transport.js:31)
at Request.<anonymous> (polling-xhr.js:93)
at Request.Emitter.emit (index.js:145)
at Request.onError (polling-xhr.js:242)
at polling-xhr.js:205
Importantly, there is no attempt to actually contact the server at all. The server never receives a connection request and wireshark/tcpdump confirm that no packet is ever transmitted to 192.168.1.5:4000
Obviously having to rebuild and re-run preview mode on each code change makes development pretty painful, does anyone have insight as to what the issue is here or suggestions on how to proceed?
I've had a similar problem, I solved it by adding this code to svelte.config.js:
const config = {
kit: {
vite: {
resolve: {
alias: {
"xmlhttprequest-ssl": "./node_modules/engine.io-client/lib/xmlhttprequest.js",
},
},
},
},
};
The solution was provided by this comment from the vite issues.

How to set up a socket connection on a strapi server

I am trying to integrate socket.io with strapi. But unfortunately I have been unable to do so without any proper tutorial or documentation covering this aspect.
I followed along with the only resource I found online which is:
https://medium.com/strapi/strapi-socket-io-a9c856e915a6
But I think the article is outdated. I can't seem to run the code mentioned in it without running into tonnes of errors.
Below is my attempt to implement it and I have been trying to connect it through a chrome websocket plugin smart websocket client But I am not getting any response when I try to run the server.
I'm totally in the dark. Any help will be appreciated
module.exports = ()=> {
// import socket io
var io = require('socket.io')(strapi.server)
console.log(strapi.server) //undefined
// listen for user connection
io.on('connect', socket => {
socket.send('Hello!');
console.log("idit")
// or with emit() and custom event names
socket.emit('greetings', 'Hey!', { 'ms': 'jane' }, Buffer.from([4, 3, 3, 1]));
// handle the event sent with socket.send()
socket.on('message', (data) => {
console.log(data);
});
// handle the event sent with socket.emit()
socket.on('salutations', (elem1, elem2, elem3) => {
console.log(elem1, elem2, elem3);
});
});
};
So I found the solution. Yay. I'll put it here just in case anybody needs it.
boostrap.js
module.exports = async () => {
process.nextTick(() =>{
var io = require('socket.io')(strapi.server);
io.on('connection', async function(socket) {
console.log(`a user connected`)
// send message on user connection
socket.emit('hello', JSON.stringify({message: await strapi.services.profile.update({"posted_by"})}));
// listen for user diconnect
socket.on('disconnect', () =>{
console.log('a user disconnected')
});
});
strapi.io = io; // register socket io inside strapi main object to use it globally anywhere
})
};
Found this at: https://github.com/strapi/strapi/issues/5869#issuecomment-619508153_
Apparently, socket.server is not available when the server starts. So you have to make use of process.nextTick that waits for the socket.server to initialize.
I'll also add a few questions that I faced when setting this up.
How do i connect from an external client like nuxt,vue or react?
You just have to connect through "http://localhost:1337" that is my usual address for strapi.
I am using nuxt as my client side and this is how set up my socketio on the client side
I first installed nuxt-socket-io through npm
Edited the nuxt.config file as per it's documention
modules:[
...
'nuxt-socket-io',
...
],
io: {
// module options
sockets: [
{
name: 'main',
url: 'http://localhost:1337',
},
],
},
And then i finally added a listener in one of my pages.
created() {
this.socket = this.$nuxtSocket({})
this.socket.on('hello', (msg, cb) => {
console.log('SOCKET HI')
console.log(msg)
})
},
And it works.
A clean way to integrate third-party services into Strapi is to use hooks. They are loaded once during the server boot. In this case, we will create a local hook.
The following example has worked with strapi#3.6.
Create a hook for socket.io at ./hooks/socket.io/index.js
module.exports = strapi => {
return {
async initialize() {
const ioServer = require('socket.io')(strapi.server, {
cors: {
origin: process.env['FRONT_APP_URL'],
methods: ['GET', 'POST'],
/* ...other cors options */
}
})
ioServer.on('connection', function(socket) {
socket.emit('hello', `Welcome ${socket.id}`)
})
/* HANDLE CLIENT SOCKET LOGIC HERE */
// store the server.io instance to global var to use elsewhere
strapi.services.ioServer = ioServer
},
}
}
Enable the new hook in order for Strapi to load it - ./config/hook.js
module.exports = {
settings: {
'socket.io': {
enabled: true,
},
},
};
That's done. You can access the websocket server inside ./config/functions/bootstrap.js or models' lifecycle hooks.
// ./api/employee/models/employee.js
module.exports = {
lifecycles: {
async afterUpdate(result, params, data) {
strapi.services.ioServer.emit('update:employee', result)
},
},
};
For those who are looking the answer using Strapi version 4
var io = require("socket.io")(strapi.server.httpServer)

Connect to a sails.js instance via websockets

Is it possible to connect any external application to my sails.js application via WebSockets?
I can use the underlying socket.io embedded in sails.js to talk between the client and server, that's not a problem.
But, I would like to connect another, separate, application to the sails.js server via websockets, and have those two communicate with each other that way, and I am wondering if this is possible?
If so, how can we do this?
Thanks.
Based on SailsJS documentation, we have access to the io object of socket.io, via sails.io.
From that, I just adjusted boostrap.js:
module.exports.bootstrap = function (cb) {
sails.io.on('connection', function (socket) {
socket.on('helloFromClient', function (data) {
console.log('helloFromClient', data);
socket.emit('helloFromServer', {server: 'says hello'});
});
});
cb();
};
Then, in my other nodejs application, which could also be another SailsJS application and I will test that later on, I simply connected and sent a message:
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000');
socket.emit('helloFromClient', {client: 'says hello'});
socket.on('helloFromServer', function (data) {
console.log('helloFromServer', data);
});
And here are the outputs.
In SailsJS I see:
helloFromClient { client: 'says hello' }
In my client nodejs app I see:
helloFromServer { server: 'says hello' }
So, it seems to be working just fine.

React Native with socket.io doesn't work

i create simple socket.io server and react native project and tested, but socket.io on React Native doesn't work at all.
i printed "socket.io-client" on console and it's loaded well, and i made simple HTML file with using socket.io, it works, but only React Native doesn't work.
i'm using React native 0.26.2, and socket.io 1.4.6.
this is my server code:
"strict mode";
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
io.on('connection', (socket) => {
console.log('user connected');
});
http.listen(3000, () => {
console.log('server started on 3000');
});
// web testing
app.get('/', (req, res, next) => {
res.sendFile(__dirname + '/index.html');
});
and this is rn code:
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, TextInput, TouchableHighlight, View } from 'react-native';
import "./userAgent"; //window.navigator.userAgent = "react-native";
const io = require('socket.io-client/socket.io');
class SocketChat extends Component {
constructor(props) {
super(props);
this.socket = io('localhost:3000', { jsonp: false });
this.state = {
text: null
};
}
...
}
as i heard, using React native with socket.io causes ajax long polling instead of websocket, so i added 'user-agent' trick. whether it is working or not, even connection isn't established, but if i try with browser, it works well. it will be very appreciate me that tell me what should i do.
I solved this by replacing another websocket module. Socket.IO doesn't work on Android and as someone said to me, Socket.io uses node native modules internally so it should be not working after build production app.

Socket.io as server, 'standard' javascript as client?

So i've built a simple websocket client implementation using Haxe NME (HTML5 target ofc).
It connects to
ws://echo.websocket.org (sorry no link, SO sees this as an invalid domain)
which works perfectly!
(i'm using xirsys_stdjs haxelib to use the HTML5 websocket stuff.)
I want to have a local (on my own machine) running websocket server.
I'm using Socket.io at the moment, because i cannot find an easier / simpler solution to go with.
I'm currently trying to use socket.io as socket server, but a 'standard' javascript socket implementation as client (Haxe HTML5), without using the socket.io library clientside.
Does anyone know if this should be possible? because i cannot get it working.
Here's my socket.io code:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(1337);
function handler (req, res) {
fs.readFile(__dirname + '/client.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
// WEBSOCKET IMPLEMENTATION
io.sockets.on('connection', function (socket) {
console.log("webSocket connected...");
socket.on('message', function () {
console.log("server recieved something");
// TODO: find out how to access data recieved.
// probably 'msg' parameter, omitted in example?
});
socket.on('disconnect', function () {
console.log("webSocket disconnected.");
});
});
And here's my Haxe (client) code:
static var webSocketEndPoint:String = "ws://echo.websocket.org";
//static var webSocketEndPoint:String = "ws://localhost:1337";
...
private function initializeWebSocket ():Void {
if (untyped __js__('"MozWebSocket" in window') ) {
websocket = new MozWebSocket(webSocketEndPoint);
trace("websocket endpoint: " + webSocketEndPoint);
} else {
websocket = new WebSocket(webSocketEndPoint);
}
// add websocket JS events
websocket.onopen = function (event:Dynamic):Void {
jeash.Lib.trace("websocket opened...");
websocket.send("hello HaXe WebSocket!");
}
websocket.onerror = function (event:Dynamic):Void {
jeash.Lib.trace("websocket erred... " + event.data);
}
websocket.onmessage = function (event:Dynamic):Void {
jeash.Lib.trace("recieved message: " + event.data);
switchDataRecieved(event.data);
}
websocket.onclose = function (event:Dynamic):Void {
jeash.Lib.trace("websocket closed.");
}
}
In case the Haxe code is unclear: it's using 2 extern classes for the webSocket implementation: MozWebSocket and WebSocket. These are just typed 'interfaces' for the corresponding JavaScript classes.
websocket.io! from the same guys. sample shows exact same thing that you are asking about... and something that I spent past 20 hours searching for (and finally found!)
https://github.com/LearnBoost/websocket.io
Update: Jan 2014
The websocket.io repository has not seen any activity for about 2 years. It could be because it is stable, or it could be because it is abandoned.
The same people have another repository called engine.io. In the readme they say that this is isomorphic with websocket.io... It seems that engine.io is where all the action is these days.
https://github.com/LearnBoost/engine.io
While searching for the same thing I just found https://github.com/einaros/ws/ and its server example worked for me with my pre-existing plain javascript client.
http://socket.io/#how-to-use
At the mentioned link, down towards the bottom of the page,
the socket.io documentation demonstrates as it's last
example, how to use their module as a plain
old xbrowser webSocket server.
SERVER
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket)
{
socket.on('message', function () { });
socket.on('disconnect', function () { });
});
BROWSER
<script>
var socket= io.connect('http://localhost/');
socket.on('connect', function ()
{
socket.send('hi');
socket.on('message', function (msg)
{ // my msg
});
});
</script>
Hope that's what your looking for
--Doc

Resources