losing reference to the socket in socket.io - javascript

I am having a typescript class on the server that is handling my socket.io communications that looks like below. basically it works, but ofc the server just saves the latest socket reference. (the person who last connected to the server, because the variable gets overwritten each time someone connects).
class ChatService {
private server;
private app;
private io;
private socket;
constructor(app, server) {
this.app = app;
this.server = server;
this.io = require('socket.io').listen(this.server);
this.io.set('log level', 1);
this.io.sockets.on('connection', (socket) => {
console.log('a user connected');
socket.join('test');
console.log(this.io.sockets.clients('test').length + ' - ' + socket.id);
this.socket = socket;
socket.on('message', (data) => this.onMessage());
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
}
public onMessage() {
this.socket.broadcast.to('test').emit('message', {
message: 'test message'
});
}
}
export = ChatService;
Do you have any good practise how I can have the right reference ( so that i can call socket.broadcast.to('test').emit() ). Maybe there is a way, that the client send his socket element, so that i have it on the server?

socket.on('message', (data) => this.onMessage());
Change it by this :
socket.on('message', (data) => this.onMessage(socket,data));
Then you have everything you need for broadcast and resend data.
public onMessage(socket,data) {
socket.broadcast.to('test').emit('message', {
message: 'test message'
});
}

Related

Send public message including sender Socket.io

I'm starting with socket.io and I can send private messages but How I can send a message to all,
At the following code(its for test purpose) the first user receives a private message every time an user is connected , How I can broadcast all the message to all clients including the sender?
this is the client
var socket = io('http://localhost:3000');
socket.emit('user_join', { username:'{{username}}'});
socket.on('private',function(data){
alert(data);
});
socket.on('message',function(data){
console.log(data);
});
and this is the server
var connectedUsers = []
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('user_join', function(msg){
connectedUsers[msg.username] = socket;
connectedUsers['aaa'].emit('private','private message');
socket.emit('message','public message');
});
console.log(connectedUsers.keys());
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
The documentation is good https://socket.io/docs/emit-cheatsheet/
There's lots of variations, but I think you're looking for:
io.emit('an event sent to all connected clients');

How can i send data and get data via angular to socket server

currently i am trying to send and get the data via angular client to socket server and from socket server to angular i need to get data i able to push the data but i need to know how can i push data to the api which is there in socket server and get data from the api to socket server and emit it to client
below is my
For sending data from angular client to socket server
component code
constructor(public socketService: SocketioService){
}
ngOnInit(){
this.socketService.setupSocketConnection();
}
// For sending post request
sendMsg(){
this.socketService.sendData(this.title);
}
// For getting the request
getMsg(){
this.socketService.getMsg().subscribe(res => {
console.log(res);
})
Angular service code
import * as io from 'socket.io-client';
import { Observable } from 'rxjs';
socket;
constructor() {
}
setupSocketConnection() {
this.socket = io(environment.SOCKET_ENDPOINT);
}
// for posting data
sendData(values){
console.log(values);
this.socket.emit('my message', values);
}
//for getting data
getMsg(){
return Observable.create((observer) => {
this.socket.on('grabMsg', (message) => {
observer.next(message);
});
});
}
Node server code
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
app.get('/', (req, res) => {
res.send('<h1>Hey Socket.io</h1>');
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
socket.on('my message', (msg) => {
//here i want to consume api like
// localhost:3000(post) {"title":"ss"}
console.log('message: ' + msg);
});
socket.on('grabMsg', () => {
//here i want to consume api like
// localhost:3000(get)
let ms = 'max'
io.emit(ms);
});
});
http.listen(3001, () => {
console.log('listening on *:3001');
});
so here how can i send and post data in socket server
in short i will send data to from angular client to socket server then to some api
//server-side
socket.on('grabMsg', () => {
let ms = 'max'
io.emit(ms);
});
//client-side
this.socket.on('grabMsg', (message) => {
observer.next(message);
});
In the above code you are using socket.on on both client and server-side also, use one as emit as one as on according to your requirement.
And in below code you are only emitting and there is the first parameter for emitting (any text enclosed in side quote) like below code
socket.on('grabMsg', () => {
let ms = 'max'
io.emit("thatText",ms);
});
the same text(thatText) should be on client-side too, like
this.socket.on('thatText', (message) => {
console.log(message)
});
You can use the nodeJs eventEmitter API. So you can emit an event by eventEmitter when someone hits your endpoint(GET request) and listen that event inside your socket server and vice-versa.
More details:- Custom Events in Node.js with Express framework
export class LiveSocket implements OnInit {
//define a socket
public socket = new WebSocket(environment.SOCKET_ENDPOINT);
ngOnInit() {
// Add an event listener for when a connection is open
this.socket.onopen = () => {
console.log('WebSocket connection opened. Ready to send messages.');
// Send a message to the server
this.socket.send('message');
};
// Add an event listener for when a message is received from the server
this.socket.onmessage = (message) => {
//handle getting data from server
var data = JSON.parse(message.data);
console.log(data)
};
}
}

Close the socket.io connection when user changes route in Angular 8

Socket.io closes the connection when user try to close the tab or window but it does not when user navigate to other route in same angular app, the disconnect event will not fire in that case.
server-side:
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
the socket.disconnect() method will not work.
I am trying to use CanDisconnect routing guards but does not know how to use that to close the connection.
server side:
// dependencies
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
//importing routes
var loginRouter = require('./routes/loginRoutes');
var chatRouter = require('./routes/chatRoutes');
app.use('/', loginRouter); // applying routes to the app
app.use('/', chatRouter); // applying routes to the app
// starting the server
http.listen(3000, function(){
console.log('server is listening on port '+PORT);
});
// socket.io ===================================
io_public = io.of('/public'); // namespace public
io_public.on('connection', function(socket){
socket.on('adduser', function(username){
socket.username = username;
socket.room = 'public'; //assign default public room
socket.join(socket.room);
socket.emit('server', 'you have connected to a public room');
socket.broadcast.to('public').emit('server',socket.username + ' has connected to this room');
});
socket.on('disconnect', function(){
socket.broadcast.to('public').emit('server',socket.username + ' has left the room');
socket.leave(socket.room);
});
});
client side:
var socket = io('http://localhost:3000/public');
var user = Cookies.get('user');
socket.on('connect', function(){
socket.emit('adduser', user);
});
socket.on('server',function(msg){
$('#conversation').append('<li> <b>Server: </b>'+msg+'</li>');
});
I am loading this client script in home component on dashboard/home, when user moves to dashboard/contacts it does not disconnect. It also create duplicate socket listeners also because this client script will reloaded every time the component is loaded.
starting state
move to contact routes:
Reloading home component
You can generate an Angular service for connecting and disconnecting. Call the service to Connect on the ngOnInit on the components you want and then call the disconnect method on the ngOnDestroy method.
You can also try to do the same implementing Guards like you said.
Inside component.ts
ngOnInit() {
this.chatService.connect()
}
ngOnDestroy(){
this.chatService.disconnectSocket();
}
Inside ChatService
import { io, Socket } from "socket.io-client";
private socket: Socket;
constructor() {
this.socket = io("http://localhost:4000");
}
connect(){
this.socket.connect()
}
disconnectSocket(){
this.socket.disconnect()
}

Socket.io MVC node.js emit to room

I have been looking into this Socket.io MVC node.js but I'm currently struggling.
It says in the documentation:
Socket.io API's
Since Socket.MVC is just a wrapping mechanism for Socket.io, all of
the same API's can be used using the Socket.MVC module. Please see a
list of all of the API's available by visiting the Socket.io Github
page, or http://socket.io (depending on your version)
My problem is that I cant find a way to emit socket MVC to a room.
socketMVC.to(userid).emit('message', {message:2});
Should work, but it doesn't. Any idea how I can accomplish this?
EDIT:
userid is same as assigned here:
import * as io from 'socket.io-client';
download
oninit:
this.socket = io(this.socketurl);
var privateRoom = socket.request.session.passport.user;
socket.join(privateRoom);
this.socket.on('message', (data) => {
// this.messagesCounter = this.messagesCounter + 1;
alert("OMG?");
});
edit , in server.js
io.on('connection',function(socket) {
console.log('user connected');
OnlineUsers.push(socket);
// socket.join('');
console.log(socket.request.session.passport);
console.log("user is connceted");
socketMVC.init(io, socket, {
debug: true,
filePath: ['./src/routes/sockets.js']
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('add-message',function (message) {
io.emit('message', {type:'new-message', text: message});
});
socket.on('myevent', function(someData) {
console.log("MYEVENT WORKS???????");
});
});
sockets.js
var path = require('path');
module.exports = function (socket) {
var privateRoom = socket.request.session.passport.user;
socket.join(privateRoom);
socket.on('testing', function() {
console.log('GOT SOME SORT OF RESPONSE!!!');
});
};
Replace socketMVC.to by socketMVC.io.to.

Creating a private chat between a key using a node.js and socket.io

How do I emit a message to all users in a private chat sharing a conversation_id using node.js and socket.io?
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
conversations = {};
app.get('/', function(req, res) {
res.sendfile('/');
});
io.sockets.on('connection', function (socket) {
socket.on('send message', function (data) {
var conversation_id = data.conversation_id;
if (conversation_id in conversations) {
console.log (conversation_id + ' is already in the conversations object');
// emit the message [data.message] to all connected users in the conversation
} else {
socket.conversation_id = data;
conversations[socket.conversation_id] = socket;
conversations[conversation_id] = data.conversation_id;
console.log ('adding ' + conversation_id + ' to conversations.');
// emit the message [data.message] to all connected users in the conversation
}
})
});
server.listen(8080);
You have to create a room with conversation_id and make users to subscribe to that room, so that you can emit a private message to that room it by,
client
var socket = io.connect('http://ip:port');
socket.emit('subscribe', conversation_id);
socket.emit('send message', {
room: conversation_id,
message: "Some message"
});
socket.on('conversation private post', function(data) {
//display data.message
});
Server
socket.on('subscribe', function(room) {
console.log('joining room', room);
socket.join(room);
});
socket.on('send message', function(data) {
console.log('sending room post', data.room);
socket.broadcast.to(data.room).emit('conversation private post', {
message: data.message
});
});
Here is the docs and example for creating a room, subscribing to the room and Emit message to a room:
Socket.io Rooms
Socket.IO subscribe to multiple channels
Socket.io rooms difference between broadcast.to and sockets.in
SURE: Simply,
This is what you need :
io.to(socket.id).emit("event", data);
whenever a user joined to the server,socket details will be generated including ID.This is the ID really helps to send a message to particular people.
first we need to store all the socket.ids in array,
var people={};
people[name] = socket.id;
here name is the reciever name. Example:
people["ccccc"]=2387423cjhgfwerwer23;
So, now we can get that socket.id with the reciever name whenever we are sending message:
for this we need to know the recievername.You need to emit reciever name to the server.
final thing is:
socket.on('chat message', function(data){
io.to(people[data.reciever]).emit('chat message', data.msg);
});
Hope this works well for you.!!Good Luck

Categories

Resources