2016-01-15 5 views
11

Ho un app.js che viene utilizzato per attivare due eventi quando si ricevono alcuni dati POST:Express e WebSocket ascolto sulla stessa porta

  1. Inserisci dati POST in un database
  2. Invia un messaggio a un client utilizzando un WebSocket

Ecco le app.js (solo le linee importanti)

var express = require('express'); 
var bodyParser = require('body-parser'); 
var server = require('./server'); 

var app = express(); 
var port = process.env.PORT || 3000; 

app.post('/server', server); 

app.listen(port, function(){ 
    console.log('Slack bot listening'); 
}); 

E qui è la server.js (solo le linee importanti)

var db = require('./DB'); 
var WebSocketServer = require('ws').Server; 

var insertData = function(req, res){ 

    var wss = new WebSocketServer({server: server}); 
    console.log('WebSocketServer created'); 
    wss.on('connection', function(wss){ 
     wss.send(JSON.stringify('Socket open')); 
    }); 
    wss.on('close', function(){ 
     console.log('WebServerSocket has been closed'); 
    }); 
}; 

module.exports = insertData; 

Quello che vorrei raggiungere è quello di impostare il WebSocketServer in un modo che ascoltare la stessa porta dell'applicazione. ho pensato di passare la server di var da app.js a server.js ma

  1. Credo che questo è un non un modo elegante per farlo
  2. non so come Fallo

Cosa ne pensate?

+0

Hai saltato alcune righe. Non è stato eseguito il mount del server WebSocket sull'app Express? – Zlatko

+1

Oh, e per rispondere alla tua domanda. È il solito modo, perché non è elegante? Richiede (qualcosa); myServer.mount (qualcosa); modulo come qualsiasi altro. – Zlatko

+0

Non ho montato il WebSocketServer sull'app Express perché non so come farlo. Saresti così gentile da fornire un esempio? Grazie per l'aiuto! – Mornor

risposta

23

Sulla base del codice e dei commenti, ecco un esempio semplicissimo di come potrebbe funzionare insieme.

In primo luogo, il http-server.js - una tipica applicazione espressa, salvo che non si parte il server con app.listen():

'use strict'; 

let fs = require('fs'); 
let express = require('express'); 
let app = express(); 
let bodyParser = require('body-parser'); 

app.use(bodyParser.json()); 

// Let's create the regular HTTP request and response 
app.get('/', function(req, res) { 

    console.log('Get index'); 
    fs.createReadStream('./index.html') 
    .pipe(res); 
}); 

app.post('/', function(req, res) { 

    let message = req.body.message; 
    console.log('Regular POST message: ', message); 
    return res.json({ 

    answer: 42 
    }); 
}); 

module.exports = app; 

Ora, l'esempio ws-server.js, dove creiamo il server WSS da un nodo nativo http.createServer(). Ora, si noti che è qui che importiamo l'app e forniamo a questo http.createServer nativo l'istanza dell'app da utilizzare.

avviare l'applicazione con PORT=8080 node ws-server.js:

'use strict'; 

let WSServer = require('ws').Server; 
let server = require('http').createServer(); 
let app = require('./http-server'); 

// Create web socket server on top of a regular http server 
let wss = new WSServer({ 

    server: server 
}); 

// Also mount the app here 
server.on('request', app); 

wss.on('connection', function connection(ws) { 

    ws.on('message', function incoming(message) { 

    console.log(`received: ${message}`); 

    ws.send(JSON.stringify({ 

     answer: 42 
    })); 
    }); 
}); 


server.listen(process.env.PORT, function() { 

    console.log(`http/ws server listening on ${process.env.PORT}`); 
}); 

Infine, questo campione index.html funzionerà con la creazione sia un palo e una "richiesta" Socket e visualizzare la risposta:

<html> 
<head> 
    <title>WS example</title> 
</head> 

<body> 
    <h2>Socket message response: </h2> 
    <pre id="response"></pre> 
    <hr/> 
    <h2>POST message response: </h2> 
    <pre id="post-response"></pre> 
    <script> 

    // Extremely simplified here, no error handling or anything 
document.body.onload = function() { 

    'use strict'; 

    // First the socket requesta 
    function socketExample() { 
    console.log('Creating socket'); 
    let socket = new WebSocket('ws://localhost:8080/'); 
    socket.onopen = function() { 

     console.log('Socket open.'); 
     socket.send(JSON.stringify({message: 'What is the meaning of life, the universe and everything?'})); 
     console.log('Message sent.') 
    }; 
    socket.onmessage = function(message) { 

     console.log('Socket server message', message); 
     let data = JSON.parse(message.data); 
     document.getElementById('response').innerHTML = JSON.stringify(data, null, 2); 
    }; 
    } 

    // Now the simple POST demo 
    function postExample() { 

    console.log('Creating regular POST message'); 

    fetch('/', { 
     method: 'post', 
     headers: { 
     "Content-type": "application/json" 
     }, 
     body: JSON.stringify({message: 'What is the meaning of post-life, the universe and everything?'}) 
    }) 
    .then(response => response.json()) 
    .then(function (data) { 

     console.log('POST response:', data); 
     document.getElementById('post-response').innerHTML = JSON.stringify(data, null, 2); 
    }) 
    .catch(function (error) { 
     console.log('Request failed', error); 
    }); 
    } 

    // Call them both; 

    socketExample(); 
    postExample(); 
} 
    </script> 
</body> 
</html> 

Nota avrete bisogno di un browser abbastanza recente, uno che abbia entrambe le API WebSocket e fetch per questa parte lato client, ma è comunque irrilevante, vi dà solo il senso.

+5

Waow @ Zlatko, questa è una risposta infernale.Grazie mille per il tempo che mi hai dedicato. Molto apprezzato! Funziona perfettamente. – Mornor

+0

@Zlatko Impossibile impostare il quasi equivalente utilizzando nodejs 'net' invece di 'ws'. net.createServer non accetta un'istanza del server http come l'istanziazione di una nuova istanza di ws: nuovo WSServer ({server: server}); – DKebler

+0

@DKebler la risposta qui era specifica per 'express.js' e' ws' modulo, come nella domanda. Stai cercando di avvolgere un ascoltatore 'net' attorno a express? Per cosa, esattamente? Hai una domanda correlata? – Zlatko