I'm trying to create a dummy socket for use in some of my tests
var net = require("net");
var s = new net.Socket();
s.on("data", function(data) {
console.log("data received:", data);
});
s.write("hello!");
Getting this error
Error: This socket is closed.
I've also tried creating the socket with
var s = new net.Socket({allowHalfOpen: true});
What am I doing wrong?
For reference, the complete test looks like this
it("should say hello on connect", function(done) {
var socket = new net.Socket();
var client = Client.createClient({socket: socket});
socket.on("data", function(data){
assert.equal("hello", data);
done();
});
client.connect();
// writes "hello" to the socket
});
I don't think the server is put into listening state. This what I use..
// server
require('net').createServer(function (socket) {
console.log("connected");
socket.on('data', function (data) {
console.log(data.toString());
});
})
.listen(8080);
// client
var s = require('net').Socket();
s.connect(8080);
s.write('Hello');
s.end();
Client only..
var s = require('net').Socket();
s.connect(80, 'google.com');
s.write('GET http://www.google.com/ HTTP/1.1\n\n');
s.on('data', function(d){
console.log(d.toString());
});
s.end();
Try this.
The production code app.js:
var net = require("net");
function createSocket(socket){
var s = socket || new net.Socket();
s.write("hello!");
}
exports.createSocket = createSocket;
The test code: test.js: (Mocha)
var sinon = require('sinon'),
assert = require('assert'),
net = require('net'),
prod_code=require('./app.js')
describe('Example Stubbing net.Socket', function () {
it("should say hello on connect", function (done) {
var socket = new net.Socket();
var stub = sinon.stub(socket, 'write', function (data, encoding, cb) {
console.log(data);
assert.equal("hello!", data);
done();
});
stub.on = socket.on;
prod_code.createSocket(socket);
});
});
We can create socket server using net npm module and listen from anywhere. after creating socket server we can check using telnet(client socket) to interact server.
server.js
'use strict';
const net = require('net');
const MongoClient= require('mongodb').MongoClient;
const PORT = 5000;
const ADDRESS = '127.0.0.1';
const url = 'mongodb://localhost:27017/gprs';
let server = net.createServer(onClientConnected);
server.listen(PORT, ADDRESS);
function onClientConnected(socket) {
console.log(`New client: ${socket.remoteAddress}:${socket.remotePort}`);
socket.destroy();
}
console.log(`Server started at: ${ADDRESS}:${PORT}`);
function onClientConnected(socket) {
let clientName = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(`${clientName} connected.`);
socket.on('data', (data) => {
let m = data.toString().replace(/[\n\r]*$/, '');
var d = {msg:{info:m}};
insertData(d);
console.log(`${clientName} said: ${m}`);
socket.write(`We got your message (${m}). Thanks!\n`);
});
socket.on('end', () => {
console.log(`${clientName} disconnected.`);
});
}
function insertData(data){
console.log(data,'data');
MongoClient.connect(url, function(err, db){
console.log(data);
db.collection('gprs').save(data.msg , (err,result)=>{
if(err){
console.log("not inserted");
}else {
console.log("inserted");
}
});
});
}
using telnet:
$ telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hi
We got your message (hi). Thanks!
you need to connect your socket before you can write to it:
var PORT = 41443;
var net = require("net");
var s = new net.Socket();
s.on("data", function(data) {
console.log("data received:", data);
});
s.connect(PORT, function(){
s.write("hello!");
});
It will useful code for websocket
'use strict';
const express = require('express');
const { Server } = require('ws');
const bodyParser = require('body-parser');
const cors = require('cors');
const PORT = process.env.PORT || 5555;
const INDEX = '/public/index.html';
const router = express.Router();
var urlencodedParser = bodyParser.urlencoded({ extended: false });
router.get('/', function(req, res) {
res.sendFile(INDEX, { root: __dirname });
});
const server = express()
.use(router)
.use(bodyParser.json())
.use(cors)
.listen(PORT, () => {
console.log(`Listening on ${PORT}`)
});
const wss = new Server({ server });
wss.on('connection', (ws) => {
ws.on('message', message => {
var current = new Date();
console.log('Received '+ current.toLocaleString()+': '+ message);
wss.clients.forEach(function(client) {
client.send(message);
var getData = JSON.parse(message);
var newclip = getData.clipboard;
var newuser = getData.user;
console.log("User ID : "+ newuser);
console.log("\nUser clip : "+ newclip);
});
});
});
Related
guys, I'm trying to make simple TCP server with net.Socket package I'm using the express framework.
The behaviour that Im trying to achieve is when user enters specific route to emmit data to all connected clients, doesn anyone now how could I achieve this ??
Here is my sample code:
const express = require('express');
const app = express();
const cors = require('cors');
const bodyParser = require('body-parser');
const net = require('net');
const PORT = 5000;
let connection;
const server = net.createServer((socket) => {
console.log('CONNECTED: ' + socket.remoteAddress +':'+ socket.remotePort);
connection = socket;
});
app.use(cors());
app.use(bodyParser.json());
app.get('/', (request, response) => {
response.send('VMS server');
});
app.post('/contact', (req, res) => {
const data = { hello: 'hello' }
connection.write(data);
res.send({ data: 'data emmited' })
});
app.listen(PORT, () => {
console.log(`Server running at: http://localhost:${PORT}/`);
});
server.listen(1337, function() {
console.log("Listening on 1337");
});
The problem m having here is that data is gettings emitted multiple times, because Im assigning current socket to connection variable.
Is there any other way how I can do this, could I use server variable to emit to all connected clients somehow ?
Ok, managed to solve it. Here are steps on how I solved it - create an array of clients, & when a client connected to the server , push that socket to client array when disconnected remove that item from the array... And to emit data to all clients, I created a broadcast method where I loop through client array, and call the emit method of each socket & send data.
Here is a sample code:
const express = require('express');
const app = express();
const cors = require('cors');
const bodyParser = require('body-parser');
const net = require('net');
const PORT = 5000;
let sockets = []; // array of sockets
// emmit data to all connected clients
const broadcast = (msg) => {
//Loop through the active clients object
sockets.forEach((client) => {
client.write(msg);
});
};
const server = net.createServer((socket) => {
console.log('CONNECTED: ' + socket.remoteAddress +':'+ socket.remotePort);
sockets.push(socket);
socket.on('end', () => {
console.log('DISCONNECTED: ');
// remove the client for list
let index = sockets.indexOf(socket);
if (index !== -1) {
console.log(sockets.length);
sockets.splice(index, 1);
console.log(sockets.length);
}
});
});
app.use(cors());
app.use(bodyParser.json());
app.get('/', (request, response) => {
response.send('VMS server');
});
app.post('/contact', (req, res) => {
const data = { hello: 'hello' }
broadcast(data); //emit data to all clients
res.send({ data: 'data emmited' })
});
app.listen(PORT, () => {
console.log(`Server running at: http://localhost:${PORT}/`);
});
server.listen(1337, function() {
console.log("Listening on 1337");
});
Is there any way to send error to frontend on mongoDb connection error.I had tried in a different different way but I didnt get a solution.
var express = require('express');
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
app.get('/',function(req,res){
res.send('NOT Connected....')
});
});
You can use web sockets to push this information to the UI.
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').createServer(app);
const io = require('../..')(server);
const port = process.env.PORT || 3000;
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
socket.emit('mongodb-failed', error)
});
});
server.listen(port, () => {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(path.join(__dirname, 'public')));
io.on('connection', (socket) => {
// when socket emits 'mongodb-connection-failed', this listens and executes
socket.on('mongodb-failed', (data) => {
// we tell the client to execute 'new message'
socket.broadcast.emit('mongodb-connection-failed', {
errorDetails: data
});
});
});
now at client side:
var socket = io();
socket.on('mongodb-connection-failed', () => {
console.log('you have been disconnected');
//do more whatever you want to.
});
This above example is using socket.io.
You can use any web socket library, see more here
I am using swaggerexpress middleware and swagger.
I can't get to work with socket.io
What is the proper way to attach socket.io to my server created?
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
var io = require('./api/helpers/socketio');
module.exports = app;
var config = {
appRoot: __dirname
};
SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; }
swaggerExpress.register(app);
app.listen(10010, function () {
console.log('Application is start listening on localhost:10010');
});
io.on('connection',function(socket){
console.log("A user is connected: " + socket.id);
io.emit('message', "Welcome")
});
});
io.attach(app);
With that approach, my server is not getting up, got an error on socket.io attaching to app.
If you're okay using a different port for socket.io, you could do something like this:
var io = require('socket.io')(10011);
// Or maybe in your case:
// var io = require('./api/helpers/socketio')(10011);
io.on('connection', function(socket) {
console.log('user connected');
});
On the client you'd connect to it like this:
var socket = io('http://localhost:10011');
socket.on('connect', function() {
console.log('Socket connection established');
});
I'm new to nodejs and I'm trying to solve communication issue with external system.
There is a gateway to external system which can handle websocket requests on port 5000. In the example below, when you request homepage, the nodejs opens websocket connection, then on websocket open event it sends request and waits for response which is used for the HTTP response.
Do you know how to open websocket to external system only once and handle requests based on request id?
var ws = require('ws');
var express = require('express');
var async = require('async');
var uuid = require('node-uuid');
app = express();
app.get('/', function (req, res) {
var webSocket = new ws('ws://localhost:5000/');
async.series([
function (callback) {
webSocket.on('open', function () {
webSocket.send(JSON.stringify({query:'data query', requestid: uuid.v4()}));
callback(null, 'data query');
});
},
function (callback) {
webSocket.on('message', function (data, flags) {
callback(null, data);
})
}
], function (err, results) {
res.setHeader('content-type', 'text/javascript');
res.send(results[1]);
webSocket.terminate();
});
});
var server = app.listen(3000, function () {
var port = server.address().port
console.log('Listening at %s', port)
});
Thanks for the hints. I ended with the following solution which does what I expect:
var ws = require('ws');
var express = require('express');
var uuid = require('node-uuid');
var requests = {};
app = express();
var webSocket = new ws('ws://localhost:5000/');
webSocket.on('open', function () {
console.log('Connected!');
});
webSocket.on('message', function (data, flags) {
var json = JSON.parse(data);
console.log(json.requestId);
var res = requests[json.requestId];
res.setHeader('content-type', 'text/javascript');
res.send(json.data);
delete requests[json.requestId];
});
app.get('/', function (req, res) {
var rid = uuid.v4();
requests[rid] = res;
webSocket.send(JSON.stringify({query:'data query', requestId: rid}));
});
var server = app.listen(3000, function () {
var port = server.address().port
console.log('Listening at %s', port)
});
Yesterday I started using this module. I'm trying to make a chat for do something with websockets.
I have the problem, that I don't know how to pass the message that sends a client to the server for then show it for all users. In the server side I have this code:
var ipaddress = 'localhost';
var port = 8080;
var WebSocketServer = require('ws').Server
, ws = new WebSocketServer({host:ipaddress, port:port});
ws.on('connection', function(ws) {
console.log('New connection');
ws.on('message', function(message) {
ws.send(message);
});
});
console.log('Listening to ' + ipaddress + ':' + port + ' ...');
And in the client side this other code:
jQuery(document).ready(function($) {
var content = $('#screen');
var message = $('input[type="text"]').val();
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function() {
console.log('Connected');
};
$('input[type="button"]').click(function() {
ws.send(message);
});
ws.onmessage = function(msg) {
console.log('Received message from server: ' + msg.data);
addMessage(msg.data);
}
function addMessage(message) {
content.prepend('<p><span>' + message + '</span></p>');
}
});
It's explained here:
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({host:ipaddress, port:port});
wss.broadcast = function(data) {
for (var i in this.clients)
this.clients[i].send(data);
};
// use like this:
wss.on('connection', function(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
});
});
var WebSocketServer = require('ws').Server
var webserver = new WebSocketServer({ port:3000 });
webserver.on("message",function(message) {
webserver.clients.forEach(function(client) {
client.send(message);
});
}):