I have multiple buttons with an attribute called groupName. They look like this:
SCENE I
SCENE II
SCENE III
I'm trying to figure out how to get socket.io to emit the link's groupName value when clicked. So when the first link is clicked, socket.io would emit "groupName - SCENE_I"
How could this be accomplished?
It seems you want something similar to a chat -- where a click on a link acts as a user sending a message to the server, and the server would emit that to a room (to other users, I suppose?)
If that's the case, you should take a look at this example: http://socket.io/get-started/chat/
You would do something like this on the client side:
<html>
<head>
</head>
<body>
SCENE I
SCENE II
SCENE III
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
$(document).ready(function(){
var socket = io();
// listen to server events related to messages coming from other users. Call this event "newClick"
socket.on('newClick', function(msg){
console.log("got new click: " + msg);
});
// when clicked, do some action
$('.fireGroup').on('click', function(){
var linkClicked = 'groupName - ' + $(this).attr('groupName');
console.log(linkClicked);
// emit from client to server
socket.emit('linkClicked', linkClicked);
return false;
});
});
</script>
</body>
</html>
On the server side, still taking the chat idea into consideration:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendfile('./index.html');
});
io.on('connection', function(socket){
// when linkClicked received from client...
socket.on('linkClicked', function(msg){
console.log("msg: " + msg);
// broadcast to all other users -- originating client does not receive this message.
// to see it, open another browser window
socket.broadcast.emit('newClick', 'Someone clicked ' + msg) // attention: this is a general broadcas -- check how to emit to a room
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Related
I would like to generate a random word from an array and then change the innerHTMl of an element to that word. However I would like this to happen so that multiple client browsers are receiving the same word.
Currently every browser is receiving a random word however not the same random word. I understand why this is happening - the function is being called in every browser and therefore generating a unique random word to that browser. How do I ensure that the same randomly generated word is sent out to each individual browser?
Code below:
Index.Js (server side)
var express = require('express')
var socket = require('socket.io')
//App setup
var app = express();
var server = app.listen(8000, function(){
console.log('listening to requests on port 8000')
});
//static files
app.use(express.static('public'));
//socket setup
var io = socket(server);
//listening for connection event from browser on connection fires callback function (backend)
io.on('connection', function(socket) {
console.log('made socket connection', socket.id)
//Listening for colorchange (click event from front end)
socket.on('colorChange', function(){
io.sockets.emit('colorChange')
})
});
button.js Client side
// Make connection (socket for front end)
var socket = io.connect('http://localhost:8000');
let wordList = ['cat', 'dog', 'skunk']
//Accessing DOM
let td1 = document.getElementById("td1")
//Send click to server
td1.addEventListener('click', function(){
socket.emit('colorChange');
});
//Listen for events from back end to execute on front end
socket.on('colorChange', function() {
td1.style.color = "red"
td1.innerHTML = wordList[Math.floor(Math.random() * wordList.length)] //ATTEMPT TO GENERATE RANDOM WORD
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Button Test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
<link href="/style.css" rel="stylesheet"/>
</head>
<body>
<table id="grid">
<tr>
<td id="td1">Hello</td>
</tr>
</table>
<script src="/button.js"></script>
</body>
</html>
Hi here is what you can do:
Index.Js (server side)
var express = require('express')
var socket = require('socket.io')
//App setup
var app = express();
var server = app.listen(8000, function(){
console.log('listening to requests on port 8000')
});
//static files
app.use(express.static('public'));
//socket setup
var io = socket(server);
var wordList = ['cat', 'dog', 'skunk'];
var selectedWord = wordList[Math.floor(Math.random() * wordList.length)];
// when you run server,
// you will have a selectedWord
//listening for connection event from browser on
// connection fires callback function (backend)
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
// everytime someone connecteds send to single user what selectedWord
// currently is
socket.emit('colorChange', selectedWord);
//Listening for colorchange (click event from front end)
socket.on('colorChange', function(){
// when someone wants to change
selectedWord = wordList[Math.floor(Math.random() * wordList.length)];
// we are gonna select a new one and send it to everyone
io.sockets.emit('colorChange', selectedWord);
// so on button.js where you listen this event
// it's gonna set new randomly selected word for every user :=)
})
});
button.js Client side
// Make connection (socket for front end)
var socket = io.connect('http://localhost:8000');
//Accessing DOM
let td1 = document.getElementById("td1")
//Send click to server
td1.addEventListener('click', function(){
socket.emit('colorChange');
});
//Listen for events from back end to execute on front end
socket.on('colorChange', function(word) {
td1.style.color = "red"
td1.innerHTML = word;
});
Edit:
There is also other way that you can create from frontend side and send it to server and broadcast to everyone is also acceptable for your example i'm guessing :)
I have been working on node.js project. my requirement is I want to load.txt file on browser. when I change and save this file, content should be updated. Browser should be auto refresh.
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
index.js
app.get('/', function(req, res){
res.sendFile(__dirname + '/demo.txt');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
var io = require('socket.io')(80);
var fs = require('fs');
fs.watchFile('message.text', (curr, prev) => {
console.log(`the current mtime is: ${curr.mtime}`);
console.log(`the previous mtime was: ${prev.mtime}`);
// file changed push this info to client.
io.emit('fileChanged', 'yea file has been changed.');
});
index.html
<script>
var socket = io();
socket.on('fileChanged', function(msg){
alert(msg);
});
First of all you can do this with two action:
1. Watch file change on server-side. And push info to client
You can watch file with node.js.
var app = require('express')();
var http = require('http').Server(app);
app.get('/', function(req, res){
res.sendFile(__dirname + '/cluster.json');
});
const io = require('socket.io')(http);
io.on('connection',function (client) {
console.log("Socket connection is ON!");
});
http.listen(80, function(){
console.log('listening on *:80');
});
var fs = require('fs');
fs.watchFile('cluster.json', function(curr, prev){
// file changed push this info to client.
console.log("file Changed");
io.emit('fileChanged', 'yea file has been changed.');
});
2. Catch "file changed" info and refresh page on client side
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript" src="node_modules/socket.io-client/dist/socket.io.js"></script>
<script>
var socket = io("http://localhost:80");
socket.on('fileChanged', function(msg){
alert(msg);
});
</script>
</body>
</html>
The best way to do this is using WebSockets. A very good package to work with WebSockets is Socket.io, and you can use something like chokidar or the native function fs.watch to watch the file changes and then emit an messsage.
Or if you trying to do this only for development purposes, you should check webpack, gulp or other task runner that have built-in functions to do this.
Do polling for the file using Ajax. Your server could respond with {changes: '{timestamp-of-file-modify}'}. Now check if your last seen change time differs from response time.
If there is changes: window.location.reload
I've been trying to get familiarized with socket.io so use it in a real time app. I went through the basic example, a chat room, then I used ngrok to do a test with more than one client and it's all good. Now I'm looking to use TAFFY to save a log of the conversation on deploy it to a new user that connects to it so I added another emmit to send that log, and this particular emmit doesn't seem to ever trigger the on sentence in the client's side.
These are the server instructions
io.on('connection', function(socket){
console.log("someone connected");
var chatLog={log:[]};
log().each(function (iter){ //this is the taffy var
chatLog.log.push({"usr":iter.usr,"msg":iter.msg});
});
var stringLog=JSON.stringify(chatLog);
console.log(stringLog);
socket.emit('cargaLog', stringLog);// THIS is the naughty emmit
socket.on('chat message', function(msg){
var mensaje=JSON.parse(msg);
log.insert({"usr":mensaje.usr,
"msg":mensaje.msg
});
io.emit('chat message', mensaje.usr.toUpperCase()+" dice: "+mensaje.msg);
});
});
Client's side
$(function () {
var socket = io();
socket.on('cargaLog', function(log){
alert(log); //this never happens
console.log(log);
});
$('form').submit(function(){
var mensaje=$('#m').val();
var json='{"usr":"'+person+'","msg":"'+mensaje+'"}';
socket.emit('chat message', json);
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
var html='<li><img src="defaultUsrImg.png" alt="Usr_img" heigth="40" width="40">'+(msg)+'</li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
});
I've been staring at this code for a while and none of the solutions that worked with other people work for me (i.e. using io.connect() or io.connect('http://0.0.0.0:8080') on the client's side or having an emmit from the client that asks for the server emmit to be triggered).
Anyone has any idea why this happens?
Altenatively, anyone have any idea that could help me troubleshoot this better?
Other details are:
Running windows 10
Node version 8.2.1
socket.io version 2.0.3
This how I use the node requires:
var TAFFY = require('taffy');
var express=require('express');
var app = express();
var http = require('http');
var path=require('path');
var port = process.env.PORT || 3000;
var server= http.createServer(app).listen(port);
var io = require('socket.io').listen(server);
var log=TAFFY({"usr":"SERVER",
"msg":"WELCOME"
});
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
Client html code (only the boddy because mt html includes and it would bee way too long
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script type="text/javascript" src="./socket.io/socket.io.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<!-- <script src="/mensajes.js"></script> THIS IS THE OLD CODE-->
<script >
var person = prompt("Introduce tu nombre o seudonimo", "anon"); //THIS IS THE WORKING CODE
if(person === null || person===""){
alert("Necesitas un nombre para participar");
}
else{
$(function () {
var socket = io();
socket.emit('ia iege',person);
socket.on('usrConectado',function(usr){
var html='<li><h6>'+(usr)+' se ha conectado</h6></li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
$('form').submit(function(){
var mensaje=$('#m').val();
var json='{"usr":"'+person+'","msg":"'+mensaje+'"}';
socket.emit('chat message', json);
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
var html='<li><img src="https://dujrsrsgsd3nh.cloudfront.net/img/emoticons/419693/pedreiro-1500067445.PNG" alt="Usr_img" heigth="40" width="40">'+(msg)+'</li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
socket.on('cargaLog', function(log){
console.log(log);
var oldLog=JSON.parse(log);
cargaLog(oldLog);
});
});
function cargaLog(newLog){
//newLog is an object
newLog.log.forEach(function(iter){
var msg=iter.usr.toUpperCase()+' dijo: '+iter.msg;
var html='<li><img src="https://dujrsrsgsd3nh.cloudfront.net/img/emoticons/419693/pedreiro-1500067445.PNG" alt="Usr_img" heigth="40" width="40">'+(msg)+'</li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
}
}
</script>
</body>
I reduced your code down to just the basics and I'm getting the message just fine that you were having trouble with. Here's the reduced code that works just fine:
Server code:
var express = require('express');
var app = express();
var http = require('http');
var path = require('path');
var port = process.env.PORT || 3000;
var server= http.createServer(app).listen(port);
var io = require('socket.io').listen(server);
app.get('/', function(req, res){
res.sendFile(__dirname + '/s1.html');
});
io.on('connection', function(socket) {
console.log("someone connected");
var chatLog = {log: [{usr: "someuser", msg: "somemsg"}]};
var stringLog = JSON.stringify(chatLog);
console.log(stringLog);
socket.emit('cargaLog', stringLog); // THIS is the naughty emmit
});
Client Code:
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
<script>
function dbg(x) {
let str = x;
if (typeof x === "object") {
str = JSON.stringify(x);
}
$("#log").append("<div>" + str + "</div>");
}
$(function() {
var socket = io();
socket.on('cargaLog', function(log) {
dbg(log);
});
});
</script>
</head>
<body>
Empty Content, waiting for message to arrive.
<div id="log"></div>
</body>
</html>
When I load the page, the browser immediately displays the cargaLog message that you were having trouble with. I would suggest that you backtrack to something super simple like this until you prove it works and then add things back one at a time until you find what is introducing the problem. If this code does not work for you, then you must have something goofed up in your environment and I'd probably do a reinstall of various components (socket.io, node.js, express, etc...).
Try
socket.emit('chat message' , { usr: person, msg: mensaje});
I think you can try to look at this repository https://github.com/egin10/socket-chat-example/blob/master/app.js for your server side.
and you can try this one for your client side https://github.com/egin10/socket-chat-example/blob/master/chat.html
Note: Just remember about socket.on(params, callback), it's for fetching data from emmiter, and io.emit(params, obj) on server side is for emmiting data.
so, you must make sure about what is your emmiting to server or client and what's your fetching (socket.on()) from serveror client must have same params.
and you must make sure about your object is var chatLog={log:[]};. if you want to get log, you must do like this chatLog.log.
It's work to me. i hope it can help you.
The chat is programmed in nodejs using websockets from socket.io library and i have a client that also uses websockets from socket.io but I don't manage to make the two work together. For some reason the client doesn't send the message to the server (I have a console.log function that should write to console when it receives a message but it doesn't write anything).
The code for the server is:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
io.emit('chat message', msg);
});
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
And for the client is :
<!DOCTYPE html>
<html>
<head>
<style>
* { margin:0; padding:0; font-size:11px; font-family:arial; color:#444; }
body { padding:20px; }
#message-list { list-style-type:none; width:300px; height:300px; overflow:auto; border:1px solid #999; padding:20px; }
#message-list li { border-bottom:1px solid #ccc; padding-bottom:2px; margin-bottom:5px; }
code { font-family:courier; background:#eee; padding:2px 4px; }
</style>
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script>
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
log('<span style="color:#888">Sending "' + message + '" to the server!</span>');
}
// Outputs to console and list
function log(message) {
var li = document.createElement('li');
li.innerHTML = message;
document.getElementById('message-list').appendChild(li);
}
// Create a socket instance
socket = new WebSocket('ws://localhost: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>
</head>
<body>
<p>Messages will appear below (and in the console).</p><br />
<ul id="message-list"></ul>
<ul style="margin:20px 0 0 20px;">
<li>Type <code>socket.disconnect()</code> to disconnect</li>
<li>Type <code>socket.connect()</code> to reconnect</li>
<li>Type <code>sendMessageToServer('Your Message')</code> to send a message to the server</li>
</ul>
</body>
</html>
Do you have any idea what is wrong here?
Thanks in advance!
You have a couple issues based on my knowledge. If they are all fixed, it should work.
The connection socket.io.js file should be your own one. In your case, I am guessing it is <script src="http://localhost:3000/socket/socket.io.js"></script> I am not 100 percent sure because your port could vary.
You didn't define socket properly on your client side. Define it as this: var socket = io();. The way you did it is socket = new WebSocket('ws://localhost:8080'); Where WebSocket is not defined. And, the code will create a new websocket server, which you already did in your server code. What you need to do at client side is only connect to the server.
You must use the same channel to let the client and server to communicate. So in your client code, you should send message like this socket.emit('chat message', 'content you want to send'.
I don't know why you emit the message at server side again BTW. I am assuming you are sending message from client to server. So you shouldn't have emit command in your server code.
If all the four things been fixed, it will work.
In case my expression is not clear, I wrote a super simple example for you:
Server side:
let io = socketio(server.listener);
io.on("connection", function(socket) {
console.log("A user connected");
// auto messages when a user is connected
setTimeout(function() {
socket.send("message at 4 seconds");
}, 4000);
setTimeout(function() {
socket.send("message at 8 seconds");
}, 8000);
// callback when a user disconnected
socket.on("disconnect", function(){
console.log("A user disconnected");
});
// receive message from client
socket.on("client-server", function(msg) {
console.log(msg);
});
});
// you put this code anywhere when you need to send message from server to client
io.emit("server-client", "server to client message");
Client side:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('server-client', function(data) {document.write(data)});
socket.emit('client-server', 'test message');
</script>
<body>Hello world</body>
</html>
My server code is written in typescript so never mind the let key word, double quote and so on.
I want to use nodeJS in my PHP web app. I followed the nodejs tutorial and that works fine when I run on localhost:3000 but I want to run on url like this localhost/final/chat/chat_index.html file. So What I did is following code
chat_index.html
<div id="newUser">
<form id="user">
<input id="username">
<input type="submit">
</form>
</div>
$(document).ready(function(){
var socket = io.connect('http://localhost:3000/final/chat/chat_index.html',
{resource:'https://cdn.socket.io/socket.io-1.2.0.js'});
$('#user').submit(function(){
socket.emit('new user', $('#username').val());
});
}); // document.ready ends here
</script>
index.js This is server side JS file
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/final/chat/chat_index.html', function(req, res){
res.sendFile(__dirname + '/chat_index.html');
});
io.on('connection', function(socket){
console.log('connected user');
socket.on('new user', function(user){
console.log(user);
});
});
http.listen(3000, function(){
console.log('listening to port');
});
Above chat_index.html page loads which shows the form on it. When I submit some data through this form server side js is not getting the data.
Is something missing in my code or I am doing something wrong in my code.
Thanks in advance
If you wish to run socket on an specific route, you can use room/namespace
http://socket.io/docs/rooms-and-namespaces/#
Example ( server )
var finalChat = io.of("/final/chat");
finalChat.on('connection', function(socket){
console.log('connected user');
socket.on('new user', function(user){
console.log(user);
});
});
If you want Independence private chat rooms, you may want to use id base socket rooms
Which version of express are you using? I believe in express 4 it should be:
var http = require('http').createServer(app);
On the client side could you also try using:
var socket = io.connect();
then load the resource in as a script tag?