Klaus1: Frage zu Node.js und 2 laufenden Listener (net und websocket)

Hallo,

ich habe in einem Script 2 Listener gestartet, einmal für das net-Modul und einmal für das Websocket-Modul.

Innerhalb der jeweiligen Listener habe ich Funktionen definiert. Z.B. (verkürzt):

net.createServer(function (socket) {
	function nettest(message) {
			console.log("yeah: "+message);
	}
}).listen(1234);


var WebSocketServer = require('ws').Server
  , wss = new WebSocketServer({host:'localhost',port: 4711});

var chat = {
	run: function(){
		wss.on('connection', function(ws) {
			ws.on('message', function(message) {
				console.log('received: %s', message);
				net.nettest(message);
			});			
		});	
	},

}
chat.run();

Kann ich jetzt aus einem 2. Listener heraus die Funktion des ersten aufrufen? (und auch umgekehrt) Ein Versuch mit net.nettest("nachricht"); hat nicht funktioniert (net.nettest is not a function).

LG Klaus

  1. Hey,

    Innerhalb der jeweiligen Listener habe ich Funktionen definiert.

    Warum Zwei?

    Hm, vielleicht ist es zielführend, wenn du das, was du ausführen möchtest, in ein Modul verpackst. Dann kannst du die Methode des Moduls in dem jeweiligen Listener aufrufen.

    Gruß
    Jo

    1. Hey Jo,

      der erste ist ein reiner tcp-Socket, über den kommuniziert ein System, das keine Websockets versteht (irgendeine sehr rudimentäre auf C basierende Umgebung). Ich möchte nun auch Browser-Clients mit diesem System kommunizieren lassen, aber die Browser verstehen nur Websocket-Verbindungen. Die auf tcp-Sockets laufenden Systeme sprechen miteinander (über client.write(message), wobei client das Socket-Objekt ist), die auf Websockets ebenso (hier ist es client.socket.send(message), client ist hier auch das Websocket-Objekt).

      Ich habe Dich leider nicht verstanden, was ich wie in ein Modul verpacken müsste, damit ich die Methoden aufrufen kann.

      LG Klaus

      1. Hey Jo,

        der erste ist ein reiner tcp-Socket, über den kommuniziert ein System, das keine Websockets versteht (irgendeine sehr rudimentäre auf C basierende Umgebung). Ich möchte nun auch Browser-Clients mit diesem System kommunizieren lassen, aber die Browser verstehen nur Websocket-Verbindungen. Die auf tcp-Sockets laufenden Systeme sprechen miteinander (über client.write(message), wobei client das Socket-Objekt ist), die auf Websockets ebenso (hier ist es client.socket.send(message), client ist hier auch das Websocket-Objekt).

        Ah, ergibt Sinn.

        Ich habe Dich leider nicht verstanden, was ich wie in ein Modul verpacken müsste, damit ich die Methoden aufrufen kann.

        Im Prinzip ist ein Modul nichts anderes als ein Objekt, welches von überall aufgerufen werden kann. Etwa so :

        var modul = require('modul')
        
        modul.foo()
        

        In modul.js wird dann etwas zurück gegeben:

        
        module.exports  = _self = {
        
        	foo: function () {
        		//Do stuff
        	}
        
        }
        
        

        So könntest du in beiden Listenern auf die gleichen oder unterschiedliche Methoden zugreifen.

        Aber ich überlege gerade... was du sicher eigentlich möchtest ist, wenn ein Event in einem Listener auftaucht, dass es über die andere Socketlist emittiert wird, oder?

        Gruß
        Jo

  2. Tach!

    net.createServer(function (socket) {
    	function nettest(message) {
    			console.log("yeah: "+message);
    	}
    }).listen(1234);
    

    Kann ich jetzt aus einem 2. Listener heraus die Funktion des ersten aufrufen? (und auch umgekehrt)

    Prinzipiell ja.

    Ein Versuch mit net.nettest("nachricht"); hat nicht funktioniert (net.nettest is not a function).

    nettest ist ja auch nur eine lokale Funktion innerhalb der anonymen Funktion. Die dürfte überhaupt nicht aufgerufen werden können, so wie dieses Stück Code aussieht.

    dedlfix.

    1. Hallo,

      ich stelle mal den logischen Teil des Quellcodes hier rein. Im Grunde sind das also zwei Chats und mein Versuch ist es, dass sich beide Parteien untereinander unterhalten können. D.h. schreibt die eine Partei etwas, soll die andere Partei davon erfahren und auch antworten können.

      LG Klaus

      // Load the TCP Library
      var net = require('net');
      
      // Load Websocket Library
      var WebSocketServer = require('ws').Server
        , wss = new WebSocketServer({host:'localhost',port: 4711});
      
      
      // Keep track of the socket clients
      var s_clients = [];
      
      // Start a TCP Server
      net.createServer(function (socket) {
      	// Identify this client
      	socket.name = socket.remoteAddress + ":" + socket.remotePort 
      
      	// Put this new client in the list
      	s_clients.push(socket);
      
      	// Send a nice welcome message and announce
      	socket.write("Welcome " + socket.name + "\n");
      	broadcast(socket.name + " joined the chat\n", socket);
      
      	// Handle incoming messages from clients.
      	socket.on('data', function (data) {
      		test = JSON.stringify(data);
      		broadcast(socket.name + " wrote > " + data, socket);
      		console.log(test);
      		console.log(convert_hex2text(data));
      	});
      
      	// Remove the client from the list when it leaves
      	socket.on('end', function () {
      		s_clients.splice(s_clients.indexOf(socket), 1);
      		broadcast(socket.name + " left the chat.\n");
      	});
      	socket.on('close', function () {
      		s_clients.splice(s_clients.indexOf(socket), 1);
      		broadcast(socket.name + " left the chat.\n");
      	});
      
      	socket.on('error', function (err) {
      		process.stdout.write("Got a socket error... client removed from list\n");
      		s_clients.splice(s_clients.indexOf(socket), 1);
      		broadcast(socket.name + " left the chat.\n");
      		process.stdout.write(err.stack);
      	});
      
      	socket.on('timeout', function () {
      		s_clients.splice(s_clients.indexOf(socket), 1);
      		console.log('Socket timed out!');
      		socket.end();
      	});
      
      	// Send a message to all clients
      	function broadcast(message, sender) {
      		s_clients.forEach(function (client) {
      			// Don't want to send it to sender
      			if (client === sender) {
      				try {
      					//	client.write('Got your message!');
      					return;
      				}
      				catch (err) {
      					console.log('cannot send message:'+err.stack);
      				}
      			}
      			try {
      				client.write(message);					// Sends Socket-Message to client
      			}
      			catch (err) {
      				console.log('cannot send message: '+err.stack);
      			}
      		});
      		// Log it to the server output too
      		process.stdout.write(message);
      	}
      
      
      }).listen(1234);
      
      // Put a friendly message on the terminal of the server.
      console.log("Socket-Server listening on port 1234\n");
      
      
      // ==========================================================================================================================================
      // HERE BEGINS THE WEBSOCKET PART
      // ==========================================================================================================================================
      
      var ws_clients = [];
      var chat = {
      
      	run: function(){
      		wss.on('connection', function(ws) {
      			ws.on('message', function(message) {
      				console.log('received: %s', message);
      				chat.dispatch(ws, message);
      			});
      			
      			ws.on('close', function() {
      				chat.removeClient(ws);
      			});
      		});	
      	},
      	
      	removeClient: function(ws){
      		ws_clients.forEach(function (client) {
      			if(client === ws){
      				console.log('remove client '+client);
      				ws_clients.splice(ws_clients.indexOf(ws), 1);
      			}
      		});
      	},
      	
      	registerClient: function(ws, client){
      		ws_clients.push(ws);
      	},
      	
      	broadcast: function(message,fromSocket){
      		chat.broadcastCommand(message,fromSocket);
      	},
      
      	broadcastCommand: function(cmd,fromSocket){
      		ws_clients.forEach(function (client) {
      			if (client === fromSocket) {
      				// do nothing, otherwise it's a simple echo server
      				return;
      			} else {
      				try{		
      					client.socket.send(cmd);
      					client.write(cmd);
      				} catch(error){
      					clients.splice(clients.indexOf(client.socket), 1);
      					console.log(error);
      				}
      			}
      		});
      	},
      	
      	dispatch: function(ws, message){
      	
      		var cmd = '';
      		var param = '';
      
      		if(message.includes('/')){
      			cmd = message.split(' ')[0];				// get command, left part of message 
      			param = message.split(' ')[1];				// get parameter, right part of message
      			param = param.substring(0,param.length-1);		// cut off last char 
      		}
      		switch(cmd){
      			case '/connect':
      				var msg = param.replace(' ','').replace(/(<([^>]+)>)/ig,"");
      				if(msg != ''){
      					chat.registerClient(ws, msg);
      				}
      				break;
      			default:
      				chat.broadcast(param, ws);
      				console.log('unkown message: '+message);
      		}
      		
      	}
      
      }
      
      chat.run();
      
      // Put another friendly message on the terminal of the server.
      console.log("WebSocket-Server listening on port 4711\n");
      
      
      1. Hallo Leute,

        auch wenn keiner mehr geantwortet hat, möchte ich euch meine Lösung nennen. Es gibt für node.js auch ein kleines weiteres Modul namens node-websockify. Dieses dient als Proxy zwischen Websocket und tcp Socket.

        Zudem ist es recht einfach zu implementieren:

        var websockify = require('node-websockify');
        websockify({
        	source: 'localhost:4711',
        	target: 'localhost:1234'
        });
        

        Ich musste allerdings im Quellcode vom node-websockify.js eine Zeile auskommentieren, die mir ansonsten einen Fehler geschmissen hat.

        Zeile 21: // console.log(client.upgradeReq.url);

        Das client.upgradeReq Property wurde seit Version 3 aus dem ws Module entfernt.

        LG Klaus