I have a Nodejs Server.js code :
first Concept :
var http = require('http');
var express = require('express');
var app = express();
var path = require('path');
var conn= http.createServer(app).listen(3000, function () {
console.log("server Running at Port 3000");
});
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({server: conn});
and i have a index.html code with java script :
<html>
<body>
<script src="myscript.js"></script>
</body>
</html>
inside myscript.js i have :
var connection = new WebSocket('ws://localhost:3000');
This is working fine when i open http://localhost:3000 on browser .
second Concept :
my server.js :
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 3000}) ;
wss.on('connection', function (connection) {
});
wss.on('listening', function () {
console.log("Server started...");
});
and HTML and client java script is similar as above .
This is not working when i open http://localhost:3000 on browser . why ? i want to clarify my doubt . Why the first method working and second is not working ?
To specifically answer your question: why web socket behave differently on nodejs? the answer is: It shouldn't. In the second version of your code you are not serving any HTML or JS files to the client on the port 3000 so the browser can't download any HTML.
If you want it to work as expected then you need to serve some HTML and JS files to the browser that visits http://localhost:3000/ or otherwise it will not be able to connect.
I wrote some example code - both server-side and client-side - on how to use WebSocket to do exactly what you are trying to do here. It's available on GitHub and I originally wrote it for this answer: Differences between socket.io and websockets.
The relevant parts of the source code for your question here are:
WebSocket Server
WebSocket server example using Express.js:
var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
console.error('websocket connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js
WebSocket Client
WebSocket client example using vanilla JavaScript:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m) { log("error"); });
s.addEventListener('open', function (m) { log("websocket connection open"); });
s.addEventListener('message', function (m) { log(m.data); });
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html
Instead of debugging a code that it not working, sometimes it's better to start from something that works and go from there. Take a look at how it all works and feel free to change it and use it in your projects - it's released under MIT license.
Related
I have implemented a user interface to do some wizard of oz testing. I have a user-side page (Page A), and a second page, the wizard page (Page B). They use the same data and page B receives some information from page A to load the correct data. When the user asks questions on page A, the question is sent to page B, and an answer should be sent back to page A. The problem is that Page A is open on device A and page B is open on Device B (both are on the same server).
I am trying to implement the communication between page A and page B using socketIO. I searched for hours and didn't find a complete example of connecting two apps using socketIO. They usually open the same app in multiple windows. That won't help me. My understanding so far is that I should create a server for each app, and then have the two servers communicate with each other. What I have so far doesn't work and no communication is happening. What I have is as follow:
for page A (index.html):
I added a index.js server file:
// Import packages
const express = require("express");
const socketIO = require("socket.io");
const path = require("path");
// Configuration
const PORT = process.env.PORT || 3000;
//const INDEX = path.join(__dirname, 'index.html');
const INDEX = path.join(__dirname, 'index.html');
console.log("INDEX", INDEX);
//const WIZARD = path.join(__dirname, 'wizard.html');
// Start server
const server = express()
//.use((req, res) => res.sendFile(INDEX), (req, res) => res.sendFile(WIZARD))
.use((req, res) => res.sendFile(INDEX))
.listen(PORT, () => console.log("Listening on localhost:" + PORT));
// Initiatlize SocketIO
const io = socketIO(server);
var other_server = require("socket.io-client")('http://localhost:4000');
other_server.on("connect",function(){
other_server.on('message',function(data){
// We received a message from Server 2
// We are going to forward/broadcast that message to the "Lobby" room
io.to('lobby').emit('message',data);
});
});
io.sockets.on("connection",function(socket){
// Display a connected message
console.log("User-Client Connected!");
// Lets force this connection into the lobby room.
socket.join('lobby');
// Some roster/user management logic to track them
// This would be upto you to add :)
// When we receive a message...
socket.on("message",function(data){
// We need to just forward this message to our other guy
// We are literally just forwarding the whole data packet
other_server.emit("message",data);
});
socket.on("disconnect",function(data){
// We need to notify Server 2 that the client has disconnected
other_server.emit("message","UD,"+socket.id);
// Other logic you may or may not want
// Your other disconnect code here
});
});
For the same app, to the index.html I added the following script:
<script type="text/javascript">
// Get WebSocket
var socket = io.connect('http://localhost:3000');
// Client
socket.on('connect', function(){
socket.emit("message","This is my message");
socket.on('message',function(data){
console.log("We got a message: ",data);
});
});
// Join a channel
var room = "test";
socket.emit("join", room);
let msg = "hello helloo helloooo from index.html";
socket.emit("new_message", msg);
socket.on("new_message", function (msg) {
console.log("sending a message through server from index.html", msg);
});
</script>
For the second app, wizard.html I added a server file, index.js:
// Import packages
const express = require("express");
const socketIO = require("socket.io");
const path = require("path");
// Configuration
const PORT = process.env.PORT || 4000;
//const INDEX = path.join(__dirname, 'index.html');
const INDEX = path.join(__dirname, 'wizard.html');
console.log("INDEX", INDEX);
//const WIZARD = path.join(__dirname, 'wizard.html');
// Start server
const server = express()
//.use((req, res) => res.sendFile(INDEX), (req, res) => res.sendFile(WIZARD))
.use((req, res) => res.sendFile(INDEX))
.listen(PORT, () => console.log("Listening on localhost:" + PORT));
// Server 2
const io = socketIO(server);
io.sockets.on("connection",function(socket){
// Display a connected message
console.log("Server-Client Connected!");
// When we receive a message...
socket.on("message",function(data){
// We got a message. I don't know, what we should do with this
});
});
and to the wizard.html, I added the script below:
<script type="text/javascript">
// Get WebSocket
//var socket = io();
var socket = io.connect('http://localhost:4000');
// Join a channel
var room = "test";
socket.emit("join", room);
let msg = "hello helloo helloooo from wizard";
socket.emit("new_message", msg);
socket.on("new_message", function (msg) {
console.log("sending message through server from wizard", msg);
});
/*
*/
</script>
I also added <script src="/socket.io/socket.io.js"></script> to both apps, index.html, and wizard.html.
In wizard.html I get this error:
POST http://localhost:4000/socket.io/?EIO=3&transport=polling&t=OAp7bZr 400 (Bad Request)
and in index.html I get this error:
Access to XMLHttpRequest at 'http://localhost/socket.io/?EIO=3&transport=polling&t=OAp7k5w' from origin 'http://localhost:3000' has been blocked by CORS policy:
If you can help me figure out what I am missing or if you know of any complete working example similar to what I am trying to accomplish, I would very much appreciate it if you let me know.
It would be even more helpful if someone could use the code and scenario I provided here and write a minimum working example in which the two apps, a.html, and b.html, can communicate through socketIO.
I've been working on a chat application using node.js and socket.io . I'm trying to run it over https .I'm a newbie in node.js and socket.io so please bear with me . Every help will be highly appreciated. I follow the instructions from here : http://kaworu.jpn.org/javascript/node.js%E3%81%AB%E3%82%88%E3%82%8BHTTPS%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9
but i get this error :
GET https://mydomain.link:3000/socket.io/?EIO=3&transport=polling&t=1502934404775-5 net::ERR_INSECURE_RESPONSE
here is the code
server.js
var https = require('https');
var fs = require('fs');
var ssl_server_key = 'server_key.pem';
var ssl_server_crt = 'server_crt.pem';
var port = process.env.PORT || 3000;
var options = {
key: fs.readFileSync(ssl_server_key),
cert: fs.readFileSync(ssl_server_crt)
};
https.createServer(options, function (req,res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end("Hello, world\n");
}).listen(port);
clientside (chatnew.js)
$(function(){
var socket = io.connect('https://mydomain.link:3000');
});
Thank you in advance !
I have a few questions about configuring socket.io for my node.js application.
When requiring var socket = require('socket.io')( /* HERE */ ), do I need to input the port my server listens where the /* HERE */ is at?
Right below the above line, I have another require function, for a .js file that contains a few constants and a function (see below). When I try to refer to 'socket' in that file it says it's undefined. But since this line is below the require line for the socket.io middleware seen above, why does it say 'undefined'?
const numbers = '1234'
function asd(req,res,next) {
socket.emit('a')
}
module.exports = {
asd
}
For configuring client-side socket.io, I added this line:
var socket = io.connect('https://mydomain')
Do I need to say 'mydomain:port' or is 'mydomain' enough?
This is how you use socket.io
var http = require('http');
var express = require('express');
var path = require('path');
var app = http.createServer();
var io = require('socket.io')(app);
var port = 8081;
io.on('connection', function(socket){
socket.on('event1', function (data) {
console.log(data);
socket.emit('event2', { msg: 'delivered' });
});
});
app.listen(port);
Answer to your second question
Yes, you will need to specify the port you are using
<script src="socket.io.js"></script>
<script>
var socket = new io.Socket();
socket.connect('https://mydomain:8081')
socket.on('your_event',function() {
console.log('your_event receivid from the server');
});
</script>
Here socket will connect to port 8081
This is a simple server side code
var http = require('http');
var io = require('socket.io');
var port = 8081;
// Start the server at port 8081
var server = http.createServer();
server.listen(port);
var socket = io.listen(server);
// example listener
socket.on('event_2', function(client){
console.log('event_2 received');
});
// example emitter
socket.emit('event_1', { hello: 'world' });
I am reading Professional Node.js and i'm trying to understand connect HTTP middleware framework. I created a simple middleware that returns a function that replies with a custom test string:
function replyText(text) {
return function(req, res) {
res.end(text);
};
}
module.exports = replyText;
But when i try to use this middleware in a connect server. Node gives me an error:
/Users/socomo22/work/hello_world_app_v2.js:8
var app = connect.createServer(replyText('Hello World!'));
^
TypeError: undefined is not a function
But when i simply use:
var app = connect();
app.listen(8080)
It runs without giving any error. I don't understand whether i'm doing any syntatical mistake. How would i use this simple middleware? This is my connect server file:
var connect = require('connect');
// middlewares
var replyText = require('./reply_text');
var app = connect();
var app = connect.createServer(replyText('Hello World!'));
app.listen(8080, function() {
console.log('listening on 8080 port')
});
As pointed by documentation use use API to mount a middleware and a http module to create an instance of server although you can create an instance just with connect as pointed here.
As pointed by #FranciscoPresencia adding .js extension while you require a your local module is optional.
var replyText = require('./reply_text.js');
So your code should look like this and i tested it. Working as intended
var connect = require('connect')
var http = require('http')
var app = connect();
// middlewares
var replyText = require('./reply_text.js');
app.use(replyText('Hello World!'));
http.createServer(app).listen(8080, function() {
console.log('listening on 8080 port')
});
Note: Try to avoid ports like 8080, 80 etc as its a reserved ports that might be used by other apps. This sometimes may cause node to fail.
Adding the output screenshot for your reference
Here You can start server in this way...
var connect = require('connect');
var http = require('http');
var app = connect();
var replyIN = require('./connetFile.js')
app.use(replyIN('Hello there m back again'));
http.createServer(app).listen(8888,function(){console.log('Server has started');});
And this is your connectFile.js
function replyIN(text){
return function (req, res) {
res.end(text);
};
};
module.exports = replyIN;
I've got an Adobe AIR Application on the local machine that communicates with an remote node.js server script (socket-script.js) via socket connection.
Furthermore i start a new node.js process through command line and send some additional arguments to a second server script (terminal-script.js).
Question: How can i send the arguments from the terminal-script.js to socket-script.js? Afterwards the socket-script.js should broadcast the
args to the AIR Application. Anyone an idea how to connect the two independent running processes in Node.js? Thanks.
Illustration link
Use the server to communicate between processes:
socket-script.js
var net = require('net');
var app = null;
var server = net.createServer(function(socket) {
socket.on('data', function(data){
if(data.indexOf('terminal:') >-1){
if(app){
app.write(data);
}
} else if(data.indexOf('app:') >-1){
app = socket;
}
});
});
terminal-script.js:
var net = require('net');
var client = net.connect({port: 9001}, function() {
client.write('terminal:' + process.argv[2]);
});
app:
var net = require('net');
var client = net.connect({port: 9001}, function() {
client.write('app:connect');
});
client.on('data', function(data){
if(data.indexOf('terminal:') >-1){
// got terminal data
}
});
The only way that I conceive of to make this work is something like this:
1) You'll need to have terminal-script.js be listening on a socket. Like so:
var arguments = process.args.splice(2);
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(arguments[0]);
}).listen(8000, '127.0.0.1');
2) Just make a request from socket-script to the terminal script:
//somewhere in socket-script use this to grab the value from the terminal script.
var http = require('http');
var options = {
host: 'terminal-script-host.com',
port: '8000',
path: '/'
};
var req = http.get(options, function(res) {
res.on('data', function (data) {
console.log('socket-script got the data from terminal-script: ' + data);
});
});
Not sure if this helps. But I can tell you that it would be nearly impossible to "inject" something into the socket-script from the terminal-script, not in a way that would work with the same request anyways.