Socket.emit() outside socket.on() - socket.io

Do we always have to use socket.emit() inside a socket.on() like that:
io.sockets.on('connection', function (socket) {
console.log('User connected !');
retrieveDictionnary((dictionnary) =>{
socket.emit('dictionnarySend', dictionnary);
}
}
I want to create on my client side a function which ask information to the server when I click on a button:
translateServer(parameter, control){
this.socket.emit('translate', [parameter,control]);
}
But it seems that it's not working, the server never receive this message.
Thank you !

The pattern you are using above is the recommended way of interacting with a socket (ie acquiring a socket instance when the 'connection' event fires, and then calling emit() from that socket instance, etc).
If I understand your client-side requirements correctly, you are wanting to send data to the server via web sockets - are you sure the socket that you have established a web socket connection between the client and server?
For instance, if you add the following to your client-side code, you should see a success message in your console:
const socket = io.connect('YOUR SERVER ADDRESS');
socket.on('connect', () => {
console.log('connected to server!');
// [UPDATE]
// This assumes you have a <button> element on your page. When
// clicked, a message will be sent to the server via sockets
document.querySelector('button').addEventListener('click', (event) => {
// Prevent button click reloading page
event.preventDefault();
// Send message to server via socket
socket.emit('MESSAGE_ID', 'test message from client' + new Date());
});
});
Update
This shows your original server code, expanded with the detail needed to receive and print data sent from client via sockets:
io.sockets.on('connection', function (socket) {
console.log('User connected !');
// Register a server handler for any messages from client on MESSAGE_ID channel
socket.on('MESSAGE_ID', (message) => {
// Print the message received from client in console
console.log('message from client', message);
})
retrieveDictionnary((dictionnary) =>{
socket.emit('dictionnarySend', dictionnary);
}
}

Related

Socket.io don't emit after disconnect event

I want to send data from the server to the client after a disconnect socket.io event occurs.
Server :
const clients = {};
io.on('connection', socket => {
clients[socket.id] = socket;
console.log('connect : ' + socket.id);
socket.emit('socket-connect', 'connected');
socket.on('disconnect', () => {
socket.emit('socket-disconnect', 'disconnected');
delete clients[socket.id];
console.log('disconnect : ' + socket.id);
});
});
Client :
const socket = openSocket('localhost');
socket.on('socket-connect', data => {
console.log(data);
});
socket.on('socket-disconnect', data => {
console.log(data);
});
If socket connected, the server send a connect message to client and it works, but it does not send interrupted messages to the client if the disconnection occurs.
console.log('disconnect : ' + socket.id); on server showing disconnect with the socket.id.
I'm using socket.io v2.0.4 both on server and client.
How can I send data from the server if a socket disconnect event occurs?
Event: disconnect is fired upon disconnection. This simply means, for some reason, there is no connection between the client and the server.
So in this situation, you cannot send data to the client as the client is not connected. Disconnection may happen if the client's network is not available(read Internet failure) or the client environment(ex: browser) crashed or the user closed the tab.

socket.io : can a socket IO client emit function register a call back function

I am trying to send a message to the server and at the same time save that message to an array in the client. I wanted to know before i start if socketio.emit takes in a call back, something like this :
socket.emit('startRecording', {someData: 'value'}, function (response) {})
socket.io does support an ACK callback from sending a message. It is described here in the socket.io doc. Here's the example of how it would be used from the doc:
// client code
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
// server code
io.on('connection', (socket) => {
socket.on('ferret', (name, fn) => {
// send ACK response
fn('woot');
});
});
If the last argument you pass .emit() is a callback, then that callback will be called if/when the server provides an ACK response as show in the example above. This allows you to use a request/response for a given message where you get a specific response from sending a message.

Switch socket server on disconnect

I am trying to connect a new server when the first server is down and attempted in reconnect_failed. Upto now it is working fine, first server disconnects, second server connected and listening the message.
socket.on('reconnect_failed', function () {
console.log("reconnect_failed");
socket = io.connect('http://localhost:4000',{
'reconnectionDelay': 100,
'reconnect':false,
'reconnectionAttempts': max_reconnects});
console.log(socket);
});
socket.on('new message', function(msg){
console.log(msg);
document.getElementById("chat").innerHTML = msg;
});
But at the client side "new message" event is not listened by second server. Due to that socket is initiated inside reconnect failed. Is there any other way to process with less code.
What I would do is have a function to switch server on disconnection.
Something like :
function initSocket(i){
sockets = io.connect(servers[i], {
'reconnectionDelay': 100,
'reconnect':false,
'reconnectionAttempts': max_reconnects});
sockets.on("connection", function(socket){
socket.on('connect',function(data){});
socket.on('new message', function(msg){
console.log(msg);
document.getElementById("chat").innerHTML = msg;
});
socket.on('reconnect_failed', function () {
console.log("reconnect_failed");
i==0 ? 1 : 0; //switch the value of i
initSocket(i) //init a socket on the other server
});
});
}
var servers = ["http://localhost:3000","http://localhost:4000"];
initSocket(0); //start with server 0 (http://localhost:3000)
This should give you the switch between your 2 servers on disconnect, with the exact same properties and event listeners. When one crashes, the other takes over.

Socket.io sending multiple message for a single request

I am using Socket.io in a NodeJS + Typescript project, where the client sends a message to ther server and the same message and send back to the client using socket. However, every time I send a new message to the server, the number of times the server sends the message back increments by 1 - which is not how I've programmed it to work. For example, the first time I send a message "x" - the server returns the message "x". The next time I send a message, the server returns that message twice. The next time it happens three times, until the page is refreshed, when it goes back to one. I don't know whats going wrong. Here's the code:
Client:
$("#send").click(function(){
alert("Sending : " + $("#text").val());
socket.emit("toServer", {
message: $("#text").val()
});
socket.on('toClient', function (data) {
alert (data.message);
});
});
Server (app.ts):
function startSocket() {
var io = require('socket.io').listen(server, {log : false});
io.sockets.on('connection', function (socket) {
socket.on('toServer', function (data) {
console.log(data);
socket.emit('toClient', data);
});
});
}
startSocket();
By registering the event handler inside the click event you would create a new registration each time the click occurred. This would lead to all of these event handlers (depending on the number of times you clicked) to fire when the server sends the message.
In short : the server is sending it only once, you were receiving it multiple times.
Putting the socket receive function outside of the button click event works.
$("#send").click(function(){
alert("Sending : " + $("#text").val());
socket.emit("toServer", {
message: $("#text").val()
});
});
socket.on('toClient', function (data) {
alert (data.message);
});

Is it possible to use socket.io server with pure html5 websockets?

I want to use sockets in my web app. I don't want to use socket.io library on client-side. It's OK for server-side though. Can I do this?
Now with socket.io on server and pure websocket on client I have destroying non-socket.io upgrade error. I've googled that it means that I have to use socket.io-client library on client-side. Is there any way to avoid that? I don't want client to be tight with this library and use pure html5 websocket instead.
If it's not possible what should I use for server to connect with pure html5 websockets?
If someone is curious here is my server code (coffeescript file)
# Require HTTP module (to start server) and Socket.IO
http = require 'http'
io = require 'socket.io'
# Start the server at port 8080
server = http.createServer (req, res) ->
# Send HTML headers and message
res.writeHead 200, { 'Content-Type': 'text/html' }
res.end "<h1>Hello from server!</h1>"
server.listen 8080
# Create a Socket.IO instance, passing it our server
socket = io.listen server
# Add a connect listener
socket.on 'connection', (client) ->
# Create periodical which ends a message to the client every 5 seconds
interval = setInterval ->
client.send "This is a message from the server! #{new Date().getTime()}"
, 5000
# Success! Now listen to messages to be received
client.on 'message', (event) ->
console.log 'Received message from client!', event
client.on 'disconnect', ->
clearInterval interval
console.log 'Server has disconnected'
And here is a client-side
<script>
// Create a socket instance
socket = new WebSocket('ws://myservername:8080');
// Open the socket
socket.onopen = function (event) {
console.log('Socket opened on client side', event);
// Listen for messages
socket.onmessage = function (event) {
console.log('Client received a message', event);
};
// Listen for socket closes
socket.onclose = function (event) {
console.log('Client notified socket has closed', event);
};
};
</script>
I've found this library, seems OK for my needs https://npmjs.org/package/ws

Resources