I am trying to establish websocket connection between nodejs and react-native. But unfortunately it is not working.
The issue is that client side do not get connected with server via sockets.
Here is nodejs (server-side) code
const express = require('express');
const app = express();
var server = app.listen(3000, () => console.log('server connected'))
const io = require("socket.io")(server)
io.on("connect", (socket) => {
console.log("user connected");
socket.on("chat message", mssg => {
console.log(mssg);
io.emit("chat message", mssg)
})
})
app.get('/', (req, res) => {
res.send("Hey! u are connected to server");
})
Here is react-native(client-side) code
import React from 'react'
import { Button } from 'react-native'
import io from 'socket.io-client'
export default class extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.socket = io("http://localhost:3000");
this.socket.on('connect', () => console.log("connected"))
this.socket.on("chat message", mssg => {
console.log("mssg recieved in client:", mssg)
})
}
render() {
return <Button title="click to send message" onPress={() => {
this.socket.emit("chat message", "anshika this side")
}
} />
}
}
Libraries used: react-native version:0.62.1, socket.io-client version:2.3.0 (client-side), socket.io version:2.3.0 (server-side)
I solved the issue by adding ip address of my laptop instead of putting localhost as a link in react-native code
you must use your ipv4 address and the catch was to specify "transports" parameters in io as ['websocket'] what's no needed in web apps
import io from 'socket.io-client'
io('http://xxx.xxx.x.xxx:port', {
transports: ['websocket']
})
Related
There is http module to create a server and passing express app context to it and then listening to it.
I've seen express' app.listen returns a Server context
Now how to create a socket.io server using app.listen's context
I've tried the below code but it is not working.
onst express = require('express')
const socket = require('socket.io')
const PORT = 5000
const app = express()
const server = app.listen(PORT, () => console.log(`Server started on port ${PORT}`))
const io = new socket.Server(server)
io.on("connection", function(socket) {
console.log("A new socket has joined: " + socket.id)
socket.on("hello", function(data) {
console.log(data);
})
})
Code starts without throwing any error but the socket server is not starting
Are you sure your socket server is not starting? May be you have a problem on client side...
I'm added index.html with client code and it connected to backend successfully.
Checkout: https://github.com/theanurin/stackoverflow.68511005
P.S.
Server started on port 5000
A new socket has joined: IqEjjc0dBHYSHqpMAAAB
Socket IO's documentation has a section on integrating with Express. Their example code looks like this:
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
While still using the http module directly, you could perhaps replace http.createServer(app) with your app.listen call. Mind you, I'm pretty sure that app.listen actually uses http.createServer under the hood. According to their documentation they do.
I made a connection with react native 'socket.io-client', your code worked to me
Here is my react native code
import React,{ Component } from "react";
import {View,TextInput,Text,StyleSheet} from 'react-native'
import io from "socket.io-client";
export default class ChatApp extends Component{
constructor(props) {
super(props);
this.state = {
chatMessage: "",
chatMessages: []
};
}
componentDidMount() {
this.socket = io("http://127.0.0.1:5000");
this.socket.on("hello", msg => {
this.setState({ chatMessages: [...this.state.chatMessages, msg]
});
});
}
submitChatMessage() {
this.socket.emit('hello', this.state.chatMessage);
this.setState({chatMessage: ''});
}
render() {
const chatMessages = this.state.chatMessages.map((chatMessage,index) => (
<Text key={index} style={{borderWidth: 2, top: 500}}>{chatMessage}</Text>
));
return (
<View style={styles.container}>
{chatMessages}
<TextInput
style={{height: 40, borderWidth: 2, top: 500}}
autoCorrect={false}
value={this.state.chatMessage}
onSubmitEditing={() => this.submitChatMessage()}
onChangeText={chatMessage => {
this.setState({chatMessage});
}}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
height: 400,
flex: 1,
},
});
I am developing a simple app with SocketIO and I am encountering this problem. In the server I have the following code:
const httpServer = require('http').createServer();
const socketIO = require('socket.io');
const port = process.env.PORT_WS || 5001;
const io = socketIO(httpServer, { cors: { origin: '*' } });
io.on('connection', (socket) => {
console.log('Connected to socket');
socket.on('join-room', () => {
console.log('joined room')
});
});
httpServer.listen(port, () => {
console.log(`Listening on the port ${port}`);
});
In the client I have the following code:
import { io } from 'socket.io-client';
export default class SocketConnection {
constructor() {
this.initializeSocketConnection();
this.initializeSocketEvents();
}
initializeSocketConnection() {
console.log('I am here');
this.socket = io('ws://localhost:5001');
}
initializeSocketEvents() {
this.socket.on('connect', () => {
console.log('Socket connected');
});
}
}
I get in the console two Socket connected messages.
This is not a re-render issue because the I am here message is logged only once.
I am using socket.io version 4.0.1 both in the client and in the backend.
So this is happening because, in React Strict Mode, constructors are called two times. React seems to hide this. As the console.log('Socket connected'); is inside an "on" event, React has no way to "hide" this. Thus, 'I am here' is going to be shown once but 'Socket connected' is going to be shown twice.
I am trying to create simple socket.io server/client
this error appears to happen when I send http request to the server
First I created html file to act as client and everything was working fine
When I started using Socket inside my React app server went nuts !
First time I start the server everything is fine and socket is working
but when I refresh the page I can't connect to server from anywhere anymore
Server code ...
const express = require('express');
class Server {
constructor({ config, router, logger }) {
this.config = config;
this.logger = logger;
this.express = express();
this.express.disable('x-powered-by');
this.express.use(router);
}
startSocket(server) {
console.log('initing');
const io = require('socket.io')(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
io.on('connection', (socket) => {
console.log('connected ' + socket.id);
});
}
start() {
return new Promise((resolve) => {
const http = this.express.listen(this.config.web.port || 6066, () => {
const { port } = http.address();
this.logger.info(`[p ${process.pid}] Listening at port ${port}`);
resolve();
});
this.startSocket(http);
});
}
}
module.exports = Server;
React code
import { io } from 'socket.io-client';
export class Socket {
constructor() {
this.socket = io('http://localhost:4000', {
rejectUnauthorized: false,
});
this.binds();
}
binds() {
this.socket.on('connect', () => {
console.log(this.socket.id);
});
this.socket.on('bong', (msg) => {
console.log(msg);
});
}
bing() {
this.socket.emit('bing', { msg: 'test' });
}
}
export default new Socket();
turns out 'socket.io' conflicts with 'express-status-monitor' which caused this problem
I'm getting a successful "A user has appeared!" connection message on the back-end. Be there seems to be no communication after the connect event.
Also, the front end keeps disconnecting and reconnecting. Is this bad?
Super socket-io novice here, just started learning tonight.
Thank you in advance for the help.
Node.JS/Express Backend:
const express = require('express')
const server = express();
const http = require('http').createServer(server);
const socketio = require('socket.io');
// ! Express --
server.use(require('cors')());
server.use(express.json());
server.get("/", (req, res) => {
res.status(200).json({
message: `You've hit the socket.io backend!`
})
})
// ! SocketIO
const io = socketio(http);
io.on('connect', socket => {
// ! Emit CheatSheet -> https://socket.io/docs/emit-cheatsheet/
// -> I believe `socket` referes to the open instance of a connection.
// -> This allows us to use functions such as:
// -> .on(eventName, cb(data)) | Use `on` when you are getting data FROM the front end.
// -> .emit(eventName, { data }) | Use `emit` when you are sending data TO the front end.
console.log(`A user has appeared!`)
socket.on("hello", data => console.log(data))
socket.on('disconnect', () => {
console.log(`A user has disappeared.`)
})
});
const PORT = process.env.PORT || 5000;
http.listen(PORT, () => console.log(`Server started on ${PORT}.`));
React Front-End (App.js):
import React, { useEffect, useState } from 'react'
// -> SocketIO
import io from 'socket.io-client';
let socket;
export default () => {
const ENDPOINT = process.env.ENDPOINT || 'http://--server-ip--/'
const [message, setMessage] = useState('Secret Message from the Front-End')
useEffect(() => {
socket = io(ENDPOINT, {
transports: ['websocket']
});
socket.emit('hello', "Hello from the front-end!")
}, [ENDPOINT]);
return (
<div>
<p>{ message }</p>
</div>
)
}
In your client you must wait to the connection be established using the appropriate events before emitting something
useEffect(() => {
socket = io(ENDPOINT, {
transports: ['websocket']
});
socket.on('connect', function(){
socket.emit('hello', "Hello from the front-end!")
});
}, [ENDPOINT]);
I am running a node server on port 3000 and an angular app on port 4200. I am attempting to send data through web sockets from the client to the server for the server. Sending data from the server to the client through web sockets is working. The screenshot shows my angular CLI info on the node server next to a browser sending messages to the server.
The browser logs the information being sent to the server(chat.service.ts:22). I join this array so that a string is sent to simplify things.(chat.service.ts:23)
The server receives socket.on('new-message') from the client, then logs the data received. Unfortunately it's an empty string, noted by the blank space created by console.log(data). The word "string" comes from console.log(typeof(data))
I included the websocket.service.ts file but I'm not actually sure if it's relevant or if I'm even using it. I am new to websockets and services in angular, and angular over all, so I'm still trying to wrap my head around how services work in angular.
Cheers,
[Image showing node server at localhost:3000 as well as client-side console outputimage
server.js:
const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
let socket = require('socket.io’);
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
const app = express();
const server = http.createServer(app);
let io = socket(server);
//Set Port
const port = process.env.PORT || '3000';
app.set('port', port);
io.on('connection', function(socket){
console.log('made socket connection', socket.id);
socket.on('new-message', function(data) {
console.log(data);
io.sockets.emit('new-message', data);
console.log(typeof(data));
});
});
websocket.service.ts:
import { Injectable } from '#angular/core';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs/Rx';
import { environment } from '../environments/environment';
#Injectable()
export class WebsocketService {
// Our socket connection
private socket;
constructor() { }
connect(): Rx.Subject<MessageEvent> {
this.socket = io(localhost:3000);
let observable = new Observable(observer => {
this.socket.on('new-message', function(data){
console.log("Received message from Websocket Server")
observer.next(data);
})
return () => {
this.socket.disconnect();
}
});
// We define our Observer which will listen to messages
let observer = {
next: (data: Object) => {
this.socket.emit('message', JSON.stringify(data));
},
};
return Rx.Subject.create(observer, observable);
}
}
chat.service.ts:
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '#angular/core';
import { Http, Headers, RequestOptions } from '#angular/http';
import { map } from "rxjs/operators";
#Injectable({
providedIn: 'root'
})
export class ChatService {
private url = 'http://localhost:3000';
private socket;
result:any;
constructor(private _http: Http) {
this.socket = io(this.url);
}
public sendMessage(messageArray) {
console.log('message array is now:')
console.log(messageArray);
this.socket.emit('new-message', messageArray.join('-'));
}
public loadPreviousMessages() {
return this._http.get("http://localhost:3000/api/messages")
.pipe(map(result => this.result = result.json().data));
}
public getMessages = () => {
return Observable.create((observer) => {
this.socket.on('new-message', (messageArray) => {
observer.next(messageArray);
});
});
}
}