I'm a newbie working with an application with MEAN stack. It is an IoT based application and using nodejs as a backend.
I have a scenario in which I have to send a broadcast to each connected clients which can only open the Socket and can wait for any incoming data. unless like a web-browser they can not perform any event and till now I have already gone through the Socket.IO and Express.IO but couldn't find anything which can be helpful to achieve what I want send raw data to open socket connections'
Is there any other Node module to achieve this. ?
Here is the code using WebSocketServer,
const express = require('express');
const http = require('http');
const url = require('url');
const WebSocket = require('ws');
const app = express();
app.use(function (req, res) {
res.send({ msg: "hello" });
});
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
}
}
wss.broadcast = function broadcast(msg) {
console.log(msg);
wss.clients.forEach(function each(client) {
client.send(msg);
});
};
server.listen(8080, function listening() {
console.log('Listening on %d', server.address().port);
});
Now, my query is when this code will be executed,
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
}
}
var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({port:8100});
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
}
}
wss.broadcast = function broadcast(msg) {
console.log(msg);
wss.clients.forEach(function each(client) {
client.send(msg);
});
};
Try the following code to broadcast message from server to every client.
wss.clients.forEach(function(client) {
client.send(data.toString());
});
Demo server code,
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 2055 },()=>{
console.log('server started')
})
wss.on('connection', (ws) => {
ws.on('message', (data) => {
console.log('data received \n '+ data)
wss.clients.forEach(function(client) {
client.send(data.toString());
});
})
})
wss.on('listening',()=>{
console.log('listening on 2055')
})
Related
i am working on a chatapp project that needs a real time chatting so i have used socketio in my server side which is written in nodejs and than used socketio-client in my main chatapp react-native project.
But now a problem is coming my socket is not initializing. I'm not able to connect my server with my main app. I am using socketio and socketio client my both the socket version are same 4.5.1 but it's not even connecting. I have tried to use old version of socket but its also not working and I have also tried to change my localhost port to 4000 but it's also not working.
My server code:
const express = require('express');
var bodyParser = require('body-parser');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
const port = process.env.PORT || 3000;
require('./src/config/database')
const user_routes = require('./src/user/users.routes');
app.use(bodyParser.urlencoded({extended: true}))
app.use(express.json())
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.use('/User', user_routes)
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('send_message',(data)=>{
console.log("received message in server side",data)
io.emit('received_message',data)
})
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(port, () => {
console.log( `Server running at http://localhost:${port}/`);
});
My app socketservice file code:
import io from 'socket.io-client';
const SOCKET_URL = 'http://localhost:3000'
class WSService {
initializeSocket = async () => {
try {
this.socket = io(SOCKET_URL, {
transports: ['websocket']
})
console.log("initializing socket", this.socket)
this.socket.on('connect', (data) => {
console.log("=== socket connected ====")
})
this.socket.on('disconnect', (data) => {
console.log("=== socket disconnected ====")
})
this.socket.on('error', (data) => {
console.log("socekt error", data)
})
} catch (error) {
console.log("scoket is not inialized", error)
}
}
emit(event, data = {}) {
this.socket.emit(event, data)
}
on(event, cb) {
this.socket.on(event, cb)
}
removeListener(listenerName) {
this.socket.removeListener(listenerName)
}
}
const socketServcies = new WSService()
export default socketServcies
Where I have marked it should be connected = true but it's false in the dev console I have done console log so check that it's connecting or not and I can see that it's not connecting. How to make it connect?
There is no error in my app or server I have checked many times and my server is also running when I am running my app.
Answering my own question
The problem was i was using android emulator and android in an emulator can't connect to localhost you need to use the proxy ip so when i add http://10.0.2.2:3000 in const SOCKET_URL = 'http://10.0.2.2:3000' than its working fine
credit goes to gorbypark who told me this in discord
I'm assuming that your front and back runs in localhost. The documentation says that if the front-end is in the same domain as the back-end, you don't need to use the URL. Since you have the options parameter declared, you can use the default argument window.location in first place:
class WSService {
initializeSocket = async () => {
try {
this.socket = io(window.location, {
transports: ['websocket']
})
console.log("initializing socket", this.socket)
this.socket.on('connect', (data) => {
console.log("=== socket connected ====")
})
this.socket.on('disconnect', (data) => {
console.log("=== socket disconnected ====")
})
this.socket.on('error', (data) => {
console.log("socekt error", data)
})
} catch (error) {
console.log("scoket is not inialized", error)
}
}
emit(event, data = {}) {
this.socket.emit(event, data)
}
on(event, cb) {
this.socket.on(event, cb)
}
removeListener(listenerName) {
this.socket.removeListener(listenerName)
}
}
Don't specify the host/port for socket-io to connect to. It can figure it out on its own.
Per documentation, it tries to connect to window.location if no URL is specified as an argument.
So instead of
this.socket = io(SOCKET_URL, {
transports: ['websocket']
})
Just do
this.socket = io()
I am not sure it works with other arguments. You could try like this
this.socket = io(undefined, {
transports: ['websocket']
})
I wrote a simple test case.
const socketioclient = require("socket.io-client");
const io = require("socket.io");
const server = io.listen(process.env.PORT);
server.on("connection", (client) => {
console.log("[SERVER] Client connected!");
client.emit("chat", "Bye!");
client.on("bye", () => {
console.log("[SERVER] Client goodbye'd us.");
client.disconnect();
})
});
const client = socketioclient("localhost:" + process.env.PORT);
client.once("connect", () => {
console.log("[CLIENT] Connected to remote server, identificating.")
this.sendIdentification();
});
client.on("chat", (msg) => {
console.log("[CLIENT] Server sends message:", msg);
if (msg.toLowerCase().indexOf("bye") != -1) {
client.emit("bye");
}
});
client.on("disconnected", () => {
console.log("[CLIENT] Disconnected.");
})
client.on("error", () => {
console.error("[CLIENT] Socket IO connection error.")
});
If you run it, nothing happens. Client does not connect to the server at all.
Following ws's instructions to create a WebSocket server:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});
An onMessage callback named incoming is created for every client, am I right?
Imagine having two million clients. This code would create two million functions. Is there a way to avoid this? Something like this would be wonderful:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('message', function incoming(ws, message) {
// Access to ws object
console.log('received: %s', message);
});
How about:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
function handleMessage(message) {
console.log('received: %s', message);
}
wss.on('message', handleMessage);
I´ve set up a websocket connection by following this "guide":
https://facebook.github.io/react-native/docs/network.html
My code so far, first block in React Native:
ws = new WebSocket("ws://localhost:8087/");
ws.onopen = () => {
ws.send('something');
};
ws.onmessage = (e) => {
this.setState({ message: e.data });
};
Second block, my node server:
const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ port: 8087 });
const messages = [];
wss.on('connection', (ws) => {
messages.forEach((message) => {
ws.send(message);
});
ws.on('message', (message) => {
messages.push(message);
console.log('Message Received: %s', message);
wss.clients.forEach((conn) => {
conn.send(message);
});
});
});
It works fine but when I deploy, do I need to set up a another server with websocket connection other than the one React Native provides?
My angularjs client websocketserver can properly send to the server, but when sending from server to client, the client doesn't register the event.
I'm using angular-websockets at the client side and ws at my express.js server
Here's my code.
server
var port = process.env.PORT || 3002;
var server = http.createServer(app); // app = express
server.listen(port);
var socketComs = require('./lib/socketcoms').connect(server);
var connect = function(server) {
var wss = new WebSocketServer({
server: server
});
wss.on('connection', function(ws) {
console.log("websocket connection open");
ws.on('message', function incoming(message) {
console.log('received', message); // THIS WORKS FINE
});
var id = setInterval(function() {
ws.send('pong', 'data 123', function(err) {
console.log('sent pong', err); // THIS IS NEVER CAUGHT BY CLIENT, err = clean
});
}, 2000); // Pong is never received
});
};
client
var connect = function() {
ws.$on('$open', function() {
console.log('wow its working');
ws.$emit('message', 'some message');
});
ws.$on('pong', function(data) {
console.log('yes', data);
});
ws.$on('$close', function(data) {
console.log('wss closed');
});
};
Can anyone see what's going wrong?
I'm using ng-websocket with PHP socket, and I have the same issue.
I just opened the ng-websocket.js and..guess what? the "ping" and "pong" events don't exist!
The "incoming" event is called "$message"...
This is how to get data from server:
ws.$on('$message', function (response) {
console.log("DATA FROM SERVER", response);