Aim: To make the chat message the user entered to appear in the console (terminal). It currently isn't logging anything and I don't know how to debug this problem. Please keep in mind that I'm a beginner to NodeJS and know probably only the basics.
Server-side NodeJS code
const http = require("http");
const host = 'localhost';
const port = 8000;
const express = require('express');
const app = express();
app.use(express.static('./'));
const socketIO = require("socket.io");
// creating the server and starting it on port 8000
const server = http.createServer(app);
server.listen(port, host, () => {
console.log(`Server is running on http://${host}:${port}`);
});
// making io object
const io = socketIO(server, {cookie: false});
// listening to connections to the server
io.on('connection', (socket) => {
console.log('a user connected');
// chat message coming to server
socket.on("details", (chatBundle) => {
console.log(join(chatBundle[0], ": ", chatBundle[1]));
});
});
Client-side HTML code
<!DOCTYPE html>
<html>
<body>
<h1>CHAT ROOM</h1>
<form onsubmit="return sendServer()">
<label for="name">Name:
<input id="name" name="name" type="text">
</label>
<label for="text">Message:
<input id="text" name="text" type="text">
</label>
<input type="submit" id="send" >
</form>
<script src="/Users/chanson/node_modules/socket.io/client-dist/socket.io.js">
</script>
<script>
const chatmsg = "details"; // added
const socket = io(); // added
function sendServer(){
var sender = document.getElementById("name");
var text = document.getElementById("text");
var tempArray = [sender, text]
socket.emit(chatmsg, tempArray)
return false; // added
};
</script>
</body>
</html>
Please help me debug this code.
in your client file import the socket io like this:
<script src="/socket.io/socket.io.js">
instead of
<script src="/Users/chanson/node_modules/socket.io/client-dist/socket.io.js">
as by default, the Socket.IO server exposes a client bundle at /socket.io/socket.io.js.
Also make sure you are hosting the client file from you server's static resources or other wise like so:
// creating the server and starting it on port 8000
app.get('/', (req, res)=>{
res.sendFile(path.join(__dirname, 'public', 'index.html'))
})
const server = http.createServer(app);
server.listen(port, host, () => {
console.log(`Server is running on http://${host}:${port}`);
});
Also in you client file's sendServer function correct the following lines:
var sender = document.getElementById("name").value;
var text = document.getElementById("text").value;
use .value to capture the user input
Related
I'm still relatively new to node.js, so I decided to practice with a simple program.
I made this program to test the connectivity between the client and the server using node.js, express and socket.io.
This is my server.js
// Create an http server with Node's HTTP module.
const http = require('http');
// Create a new Express application
const express = require('express');
const app = express();
const clientPath = `${__dirname}/../client`;
console.log(`Serving static from ${clientPath}`);
app.use(express.static(clientPath));
const socketio = require('socket.io');
// Pass the http server the Express application
const server = http.createServer(app);
const io = socketio(server);
io.on('connection', function (socket) {
console.log("There's been a connection");
socket.on("console output", function (input) {
console.log(input)
});
socket.on("text alter", function(data){
var display = "'" + data + "' An interesting set of characters";
io.sockets.emit("display string", display);
})
})
//Listen on port 8080
server.listen(8080, function () {
console.log("Listening on port 8080");
})
This is my index.js
const socket = io();
let players = [];
function serverOutput(){
socket.emit("console output", "You suck at programming");
}
function serverAlter(){
const alterInput = document.querySelector('#userinput1').value;
socket.emit("text alter", alterInput);
}
socket.on("display string", function(){
const outputArea = document.querySelector('#outputspace1');
var fullLine = document.createElement("p");
outputArea.appendChild(fullLine);
})
Lastly my index.html
<html lang="en">
<head>
<title>Home</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="main-menu" class="page-templates">
<h3>Part 1: Press the button to see the server send a message</h3>
<button onclick="serverOutput()">Server message</button>
<br>
<h3>Part 2: Type in a string, and the server will add to it</h3>
<input type="text" id="userinput1">
<div id="outputspace1">
</div>
<button onclick="serverAlter()">Create sentence</button>
<script src="/socket.io/socket.io.js"></script>
<script src="src/index.js"></script>
</body>
</html>
From how the code runs, the server is able to pick up the data from the client, but when I try to change the data and send it back, the paragraph that is meant to be outputting the string has no data. I have a feeling I implemented the "io.sockets.emit()" incorrectly, but please if you guys can enlighten me, I would be so grateful.
In the client code, when you add data to your #outputspace1 element with this:
socket.on("display string", function(){
const outputArea = document.querySelector('#outputspace1');
var fullLine = document.createElement("p");
outputArea.appendChild(fullLine);
});
All you are doing there is adding an empty <p></p> element to #outputspace1. Instead, you need to capture the data being sent back to you by declaring the right incoming function parameter on your .on() event handler and then you need to add that data to the p element you created like this:
socket.on("display string", function(newText){
const outputArea = document.querySelector('#outputspace1');
var fullLine = document.createElement("p");
fullLine.innerHTML = newText;
outputArea.appendChild(fullLine);
});
I am trying to send data bidirectionally between a node server and browser client.
I can get information from the Node server to the browser client but not vice versa. I dont understand what I am doing wrong, please help.
Node server.js
var express = require('express')
var app = express();
var http = require('http').Server(app);
var socketTx = require('socket.io')(http);
app.use(express.static(__dirname + '/'))
http.listen(3000, function(){
console.log('listening on http://127.0.0.1:3000');
});
// 1) Send initial data from node to browser
setInterval( function() {
var msg = Math.random();
socketTx.emit('Node', msg);
}, 1000);
var io = require('socket.io-client');
var socketRx = io.connect('http://localhost:3000', {reconnect: true});
// 4) Receive data from browser and log in node console
socketRx.on('Browser', function(msg){
console.log(msg);
});
Browser index.html
<html>
<head></head>
<body>
<div id="message"></div>
<script src="/socket.io/socket.io.js"></script>
<script src="socket.js"></script>
</body>
</html>
Browser socket.js
var socketRx = io();
var socketTx = io();
// 2) Receive initial data from node and display in browser
socketRx.on('Node', function(msg){
document.getElementById("message").innerHTML = msg;
// 3) Send data from browser back to node
socketTx.emit('Browser', msg);
});
I'm not familiar with socket.io, sorry if there are mistakes.
By refering to this official document, I fixed server.js as below.
It has been working fine in my environment. Please try this code.
var express = require('express')
var app = express();
var http = require('http').Server(app);
var socketTx = require('socket.io')(http);
app.use(express.static(__dirname + '/'))
http.listen(3000, function(){
console.log('listening on http://127.0.0.1:3000');
});
// 1) Send initial data from node to browser
setInterval( function() {
var msg = Math.random();
socketTx.emit('Node', msg);
}, 1000);
var io = require('socket.io-client');
io.connect('http://localhost:3000', {reconnect: true});
// 4) Receive data from browser and log in node console
socketTx.on('connection', function(socket) {
socket.on('Browser', function(msg){
console.log(msg);
});
});
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 recently started using Socket.io, and node.js as a result, and I am kind of stuck. I do not even know if this is a practical solution for my application, but hopefully someone can help.
All I have here is a webpage with a checkbox, which reports it's status to the node console, and then when a TCP client connects, it receives the status as well.
I am wondering how I would go about making this event continuous, so that the TCP client constantly receives updates on the status of the checkbox.
If anyone has any idea, please let me know, and sorry for the long code...
Server Code:
var net = require('net');
var app = require('express')(); <!-- These are mandatory variables -->
var http = require('http').Server(app);
var io = require('socket.io')(http);
var HOST = 'localhost';
var PORT = 4040;
GLOBAL.MYVAR = "Hello world";
var server = net.createServer();
server.listen(PORT, HOST);
app.get('/', function(req, res){ <!-- This sends the html file -->
//send the index.html file for all requests
res.sendFile(__dirname + '/index.html');
});
http.listen(3001, function(){ <!-- Tells the HTTP server which port to use -->
console.log('listening for HTTP on *:3001'); <!-- Outputs text to the console -->
console.log('listening for TCP on port ' + PORT);
});
<!-- everything below this line are actual commands for the actual app -->
io.on('connection', function(socket) // Opens the socket
{
socket.on('checkbox1', function(msg){ // Creates an event
console.log(msg); // displays the message in the console
MYVAR = msg; // Sets the global variable to be the contents of the message recieved
});
});
server.on('connection', function(socket){ // Opens the socket for the TCP connection
socket.write(MYVAR);
}).listen(PORT, HOST);
Client code:
<!doctype html>
<html>
<head>
<title>Socket IO Test</title>
<form action="">
<input type='checkbox' onclick='checkbox1(this);'>Checkbox1</label>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
var number = 0;
function checkbox1(cb) {
socket.emit('checkbox1', 'checkbox 1 = ' + cb.checked);
return false;
}
</script>
</body>
</html>
Cheers
I believe the issue here is that you don't have a way to reference the TCP socket. Once you do have a reference it is as easy as receiving a message and sending it.
This will work for a single client.
var net = require('net');
var app = require('express')(); <!-- These are mandatory variables -->
var http = require('http').Server(app);
var io = require('socket.io')(3000);
var s;
var HOST = 'localhost';
var PORT = 4040;
GLOBAL.MYVAR = "Hello world";
var server = net.createServer();
server.listen(PORT, HOST);
app.get('/', function(req, res){ <!-- This sends the html file -->
//send the index.html file for all requests
res.sendFile(__dirname + '/index.html');
});
http.listen(3001, function(){ <!-- Tells the HTTP server which port to use -->
console.log('listening for HTTP on *:3001'); <!-- Outputs text to the console -->
console.log('listening for TCP on port ' + PORT);
});
<!-- everything below this line are actual commands for the actual app -->
io.on('connection', function(socket) // Opens the socket
{
socket.on('checkbox1', function(msg){ // Creates an event
console.log(msg); // displays the message in the console
MYVAR = msg; // Sets the global variable to be the contents of the message recieved
s.write(MYVAR, 'utf-8');
});
});
server.on('connection', function(socket){ // Opens the socket for the TCP connection
s = socket;
s.write(MYVAR, 'utf-8');
}).listen(PORT, HOST);
This will work for multiple clients.
var net = require('net');
var app = require('express')(); <!-- These are mandatory variables -->
var http = require('http').Server(app);
var io = require('socket.io')(3000);
var sockets = [];
var HOST = 'localhost';
var PORT = 4040;
GLOBAL.MYVAR = "Hello world";
var server = net.createServer();
server.listen(PORT, HOST);
app.get('/', function(req, res){ <!-- This sends the html file -->
//send the index.html file for all requests
res.sendFile(__dirname + '/index.html');
});
http.listen(3001, function(){ <!-- Tells the HTTP server which port to use -->
console.log('listening for HTTP on *:3001'); <!-- Outputs text to the console -->
console.log('listening for TCP on port ' + PORT);
});
<!-- everything below this line are actual commands for the actual app -->
io.on('connection', function(socket) // Opens the socket
{
socket.on('checkbox1', function(msg){ // Creates an event
console.log(msg); // displays the message in the console
MYVAR = msg; // Sets the global variable to be the contents of the message recieved
for (var i = 0; i < sockets.length; i++) {
if(sockets[i]) {
sockets[i].write(MYVAR, 'utf-8');
}
}
});
});
server.on('connection', function(socket){ // Opens the socket for the TCP connection
sockets.push(socket);
socket.write(MYVAR, 'utf-8');
}).listen(PORT, HOST);
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?