I was trying to use socket.io to make a real-time collaboration editor with two different WYSIWYG Editors called summernote and froala. Server and client side both can receive and send content, however, it repeatedly refreshes stuff and I don't know why. Any advice? Thanks!
Here is part of my code:
Server side:
var express = require('express'),
app = express(),
http = require('http'),
io = require('socket.io');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(8000);
app.use(express.static(__dirname + '/public'));
console.log("Server running on 127.0.0.1:8000");
// event-handler for new incoming connections
io.on('connection', function (socket) {
// first send the history to the new client
socket.on("summer_change", function (data) {
io.sockets.emit('summer_change', {content: data.content});
});
socket.on("text_change", function (data) {
io.sockets.emit('text_change', {content: data.content});
});
});
Client:
document.addEventListener("DOMContentLoaded", function() {
// get canvas element and create context
var socket = io.connect();
var text = {
text: ''
};
$(function() {
$('#text').froalaEditor()
});
//Update summer
$('#summernote').on('summernote.change', function(we, contents, $editable) {
console.log('summernote content is changed:'+$('#summernote').summernote('code'));
var contents = $('#summernote').summernote('code')
socket.emit("summer_change",{content:contents});
});
// Change summer content from server
socket.on("summer_change", function (data){
console.log("Back from server! ");
$('#summernote').summernote('code', data.content);
});
$('#text').froalaEditor().on('froalaEditor.contentChanged', function (e, editor) {
var contents=editor.html.get();
socket.emit("text_change",{content:contents});
})
socket.on("text_change", function (data){
console.log("Back from server! ");
$('#text').froalaEditor('html.set', data.content);
});
});
Related
I am very new to this socket.io.
I have the code this is a node server code:
var express = require("express");
var app = express();
var http = require("http").createServer(app);
var socketIO = require("socket.io")(http);
var socketID = "";
socketIO.on("connection", function (socket) {
console.log("User is conneected ", socket.id);
socketID = socket.id;
});
And here is the code for a ejs file:
......
<script src="/public/js/socket.io.js"></script>
<script>
......
var socketIO = io("http://localhost:3000");
......
</script>
......
And the socket.io.js file is here:
I tried but nothing is working. The same error pops whenever I refresh the page.
I am very new to this and I really want to get it sorted as soon as possible!!
I already have a listen function just after socket.on:
http.listen(3000, function () {
console.log("Server has started running!!");
.........................
.............
})
The below code is working for me.
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
io.sockets.on('connection', function (socket) {
console.log(socket);
})
server.listen(3000, function(){
console.log('listening on *:3000');
});
<script src="/socket.io/socket.io.js" > </script>
<script>
$(function () {
var socket = io.connect();
});
</script>
socket.io.js that you have mentioned is the same as that from the https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js... check the installed version of serail io in package.json and place the same version here in the path socket.io/2.2.0 it will work
Please Check versions of socket.io in your Frontend and Backend. It should be compatible. I had same issue so I solved it with version change. Like I had 2.2.0 in my frontend so I install 1.7.2 in backend or same as frontend.
so I have this idea in my head where when you run nodejs script it starts http(express) server on port 8080 and regular tcp(net) server on port 1337. And when you connect to tcp server via netcat and send "alert" it runs alert() command on webpage via javascript. Here is the code but the if statement is not working(it is printing data but not alerting on my web browser)
var app = require("express")();
var http = require("http").Server(app);
var io = require("socket.io")(http);
var net = require("net");
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
var server = net.createServer();
io.on("connection", function(sock) {
console.log("Client connected");
server.on("connection", function(conn) {
var remoteAddress = conn.remoteAddress + ":" + conn.remotePort;
console.log("New client: " + remoteAddress);
conn.on("data", function (data) {
console.log(data.toString())
if (data.toString() == "alert") {
console.log("YES ALERT");
io.emit("HELLO");
}
});
conn.once("close", function () {
console.log(remoteAddress + " disconnected");
});
conn.on("error", function (error) {
console.log(remoteAddress + " Error: " + error);
});});
});
server.listen(1337, function() {
console.log("Listening on 1337");
});
http.listen(8080, function() {
console.log("Web server started on 8080");
});
Include socket io client js in your webpage and connect to socket server
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:1337');
socket.on('connect', function(){});
socket.on('event', function(data){ alert(data.message) });
socket.on('disconnect', function(){});
</script>
you can Change the server side code, to emit the event to work with my example above.
io.emit("event",{"message":"HELLO"});
While trying to setup a simple NodeJS server and Socket.io client to test something with WebSockets, I've stumbled into something stupid. I'm pretty sure it's something stupid I've done because I've worked with NodeJS/Socket.io before and never had this problem.
With the code below, I'm able to receive the 'tick' event from the server on the client, but the server seems unable to receive the 'ping' event from the client. 'tick' was used to make sure server->client worked, and 'ping' to test client->server.
Using latest Socket.io (1.4.6) and express (4.14.0)
server.js:
var express = require('express');
var app = require('express')();
var server = require('http').createServer(app);
var sio = require('socket.io')(server);
var path = require('path');
app.use(express.static(path.join(__dirname, 'public_html')));
// Socket.io
sio.on('connection', (socket) => {
// Store socket ID
var socketID = socket.conn.id;
// Log connection
console.log('Connection:', socketID);
// Ping event
socket.on('ping', (message) => {
console.log('Ping:', socketID, '-', (message || '(no message>'));
});
// Tick event
var tick = function(){
var now = new Date().getTime().toString();
socket.emit('tick', now);
}
setInterval(tick, 5000);
// Disconnect event
socket.on('disconnect', () => {
console.log('Disconnected:', socketID);
});
});
server.listen(4100, () => {
console.log('Listening on :4100');
});
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Websockets Benchmark</title>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
// Socket.io
var sio = io();
// Connection event
sio.on('connect', () => {
console.log('Connected');
sio.emit('ping', 'on connect');
});
// Tick event
sio.on('tick', (time) => {
console.log('Tick', time);
});
// Error event
sio.on('error', (e) => {
console.error(e);
});
</script>
</body>
hope i understood your question...
i did some work with chat by using socket.io so maybe it will help you.
here it is:
<div class="searchBox" style="height: 600px ; width: 500px">
<div style=";width:400px;border-right:1px solid black;;overflow:scroll-y;">
<b style="color: black ;text-decoration: underline">USERS:</b>
<div id="users" style="color: black"></div>
</div>
<div style=";width:300px;height:250px;overflow:scroll-y;padding:10px;">
<b style="color: black ; text-decoration: underline">CONVERSATION:</b>
<div id="conversation" style="color: black"></div>
<input id="data" style="width:200px;" />
<button id="datasend" style="color: #0f0f0f;">send</button>
</div>
and the js:
var socket = io.connect('http://localhost:8080');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatechat', function (username, data) {
$('#conversation').append('<b>'+username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updateusers', this updates the username list
socket.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('<div>' + key + '</div>');
});
});
// on load of page
$(function(){
// when the client clicks SEND
$('#datasend').click( function() {
var message = $('#data').val();
$('#data').val('');
// tell server to execute 'sendchat' and send along one parameter
socket.emit('sendchat', message);
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
server:
var app = require('./app');
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(8080, function() {
console.log("Gym Project is listening to: http://127.0.0.1:8080");
});
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// usernames which are currently connected to the chat
var usernames = {};
io.sockets.on('connection', function (socket) {
// when the client emits 'sendchat', this listens and executes
socket.on('sendchat', function (data) {
// we tell the client to execute 'updatechat' with 2 parameters
io.sockets.emit('updatechat', socket.username, data);
});
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// we store the username in the socket session for this client
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected');
// echo globally (all clients) that a person has connected
socket.broadcast.emit('updatechat', 'SERVER', username + ' has connected');
// update the list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
});
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
delete usernames[socket.username];
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
});
});
this is a very simple chat with some clients...
may it helps :)
Can't tell if the ping event is taken by Socket.io, or the following line caused an issue:
console.log('Ping:', socketID, '-', (message || '(no message)'));
Either way, by changing the event name to ev:ping (which is easier to understand anyway), and simplifying that line it's fixed! :)
I am trying to create a nodejs app that will search in various web sites using their API. The result will be sent to the client as soon as it receive result from those API using socket.io. The front end will then add those result using jQuery.
What is the best way to implement this?
So Far I have tried:
Sample code 1
At first I created a middleware for express that add the socket to the request like -
var socketMiddleWare = function(req, res, next){
io.on('connection', function(socket){
console.log(io.engine.clientsCount + " clients connected.");
req.socket = socket;
socket.on('disconnect', function(){
console.log(io.engine.clientsCount + " clients after disconnec.");
});
});
next();
};
then added this middleware to my route -
app.use('/users', socketMiddleWare, users);
It works but the problem is it create multiple event listener each time user refresh the page.
Sample code 2
So then I tried (sample code)
io.on('connection', function(socket){
console.log("user connected");
global.socket = socket;
socket.on('disconnect', function(){
console.log("disconnect");
});
socket.on('my message', function(){
console.log("My message received");
});
});
and on my test route I did
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
if(socket){
socket.emit('response', 'nothing');
}
res.render('index', { title: 'Express' });
});
module.exports = router;
It solved the previous problem of multiple event listener on refresh But most of the time it can not emit the response. And even it emit my browser can not show the result. On client side I did something like this -
var socket = io.connect('http://localhost');
socket.on('response', function(data){
console.log(data);
document.getElementById("change").innerHTML += data;
});
I can see the response in browser console but my browser show the change for a few milliseconds before it disappear.
I think the the main problem is The page loads before establishing socket connection.
I am currently learning node.js and socket.io. So please help me.
Conclusion
I do have plan to add social network features like one to one message, live friends feed update on home page etc using socket.io in future. Please let me know if there is any good documentation or open source project that can help me implementing it.
I am searching for solution for last couple of days but with no luck so far. I am ready to learn any new methodology or fully rewrite my code.
TL;DR
When a user client search for item, push contents to the client that requested the content when new data available. Data is available after processing response from website like "The Movie Database" and "TheTVDB.com" through their API.
You can use the ID of the socket to keep track of which socket to send results to.
Client
When the user then searches for something the ID is included in the query parameters.
<body>
<form>
<!-- Disable the search bar until the socket is connected -->
<input type="search" name="q" placeholder="Search" disabled>
</form>
<div id="results"></div>
<script src="/socket.io/socket.io.js"></script>
<script>
var resultsElement = document.querySelector("#results");
var search = document.querySelector("form [type=search]");
var socket = io("http://localhost:3000");
socket.on("connect", function(){
search.disabled = false;
});
socket.on("results", function(results){
for(var i = 0;i < results.length;i++){
var result = document.createElement("div");
result.textContent = results[i];
resultsElement.appendChild(result);
}
});
document.querySelector("form").addEventListener("submit", function(event){
fetch("/search?socketID=" + encodeURIComponent(socket.id) + "&q=" + encodeURIComponent(search.value));
event.preventDefault();
});
</script>
</body>
Server
When the server receives the search request it gets the socket using the socket ID sent in the query parameters and starts sending results back to the client.
var app = require("http").createServer(handler);
var io = require("socket.io")(app);
var fs = require("fs");
var url = require("url");
app.listen(3000);
function handler(req, res) {
var query = url.parse(req.url, true).query;
if(req.url.startsWith("/search")){
var results = ["things", "stuff", "items"];
// Server-side IDs have "/#" in front of them
var socket = io.sockets.connected["/#" + query.socketID];
if(socket){
// Get and send "search results"
var interval = setInterval(function(){
var popped = results.pop();
if(popped){
socket.emit("results", [query.q + " " + popped]);
}else{
clearInterval(interval);
}
}, 1000);
}
res.writeHead(204);
res.end();
}else{
fs.readFile(__dirname + "/index.html", function(err, data) {
res.writeHead(200);
res.end(data);
});
}
}
Hello guys i'm having a problem in redis pub/sub because my client does not show the message i've published in redis-cli. I used the codes found here in stackoverflow and i made some modification. Here is the link and code. I hope you can help me, my goal is to publish the message to the client index.html using redis publish in redis-cli. I've done this before but i can't make it work again. Thanks in advance guys.
Here is my client index.html
<html>
<head>
<title>PubSub</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<!-- <script src="/javascripts/socket.js"></script> -->
</head>
<body>
<div id="content"></div>
<script>
var socket = io.connect('http://localhost:3000');
var content = $('#content');
socket.on('connect', function() {
});
socket.on('message', function (message){
content.prepend(message + '<br />');
}) ;
socket.on('disconnect', function() {
console.log('disconnected');
content.html("<b>Disconnected!</b>");
});
socket.connect();
});
</script>
</body>
</html>
Here is my server.js
var express = require('express');
var app = express();
var redis = require('redis');
var http = require('http');
var server = http.createServer(app);
var socket = require('socket.io').listen(server);
var publish = redis.createClient();
app.listen(3000);
console.log("Express server listening on port 3000")
app.get('/', function (req,res) {
res.sendfile(__dirname + '/public/index.html');
});
socket.on('connection', function (client) {
var subscribe = redis.createClient();
subscribe.subscribe('pubsub');
subscribe.on("message", function (channel, message) {
publish.send(message);
});
publish.on('message', function (msg) {
});
publish.on('disconnect', function() {
subscribe.quit();
});
});
Redis will not send data to connected clients for you. You must instruct Socket.IO to emit data:
subscribe.on("message", function (channel, message) {
socket.emit('message', message);
});