2015-04-11 13 views
2

Я использую ws с node.js на стороне сервера и обычный API WebSocket на стороне клиента. Открытие соединения и обмен сообщениями несколько раз взад и вперед отлично работает. Но сокет всегда закрывается через минуту или две. Разве они не должны упорствовать? Я делаю что-то неправильно?Почему мой websocket закрывается через несколько минут?

Мой сервер node.js размещен на heroku. Я только что тестировал локально снова, используя foreman start (инструмент heroku для запуска сервера локально), и сокет не закрывается неожиданно вообще, так что, возможно, это неправильная конфигурация на героку. Во всяком случае, вот соответствующий пример кода с несколькими функциями, опущенными для краткости.

Я тестирую приложение в Chrome на OSX Yosemite, но видел такое же поведение в Chrome в Windows 7 при работе с производственной средой.

сервер:

// Client <-> Host Protocol functions. Move to a different file so that they can be shared. 
var C2H_SIGNAL_TYPE_REGISTER = "register"; 

var H2C_SIGNAL_WELCOME = "welcome"; 
var H2C_SIGNAL_TYPE_ERROR = "error"; 
var H2C_SIGNAL_TYPE_PEER_ADDED = "peer_joined"; 
var H2C_SIGNAL_TYPE_PEER_LEFT = "peer_left"; 

// Update channel endpoint names. 
var UPDATE_ENDPOINT_PEERS = "/peers"; 

// Create a signal message with all asociated default properties. 
// Signal senders should create this object and update it accordingly when 
// building a signal message to send to a peer. 
function createHostMsg(type) 
{ 
    var msg = { signalType: type }; 

    if (type == H2C_SIGNAL_WELCOME) { 
     // Since we're sending a welcome message, we need to provide a list 
     // of currently connected clients. 
     msg.peers = {}; 
     for (var addr in clients) { 
      console.log("addr " + addr); 
      var c = clients[addr].description; 
      if (c && c.id) { 
       msg.peers[c.id] = c; 
      } 
     } 
    } 

    return msg; 
} 

// require modules. 
var express = require('express'); 
var http = require('http'); 
var bodyParser = require('body-parser'); 
var multer = require('multer'); 

// Tracks connected peers. 
var clients = { }; 

// 1. Configure the application context settings. 
var app = express(); 
app.enable('trust proxy'); 
app.use(express.static(__dirname + '/public')); 
app.use(bodyParser.json()); // parse json 
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded 
app.use(multer()); // for parsing multipart/form-data 

// a. configure http routers. these will handle requests coming from app. 
app.set('port', (process.env.PORT || 5000)); 
app.get('/app', peerApp); 
app.get('/script/:name', publicScriptRouter); 

// 2. Create the http server itself, passing app to be the request handler. 
// app will handle routing and multiplexing of incoming requests to different 
// route middleware handlers. 
var http = require('http'); 
var WebSocketServer = require("ws").Server 
var httpServer = http.createServer(app); 
httpServer.listen(app.get('port')); 

// 3. Create one of these for all socket endpoints. 
var wss = new WebSocketServer({ server: httpServer, path: UPDATE_ENDPOINT_PEERS }); 

wss.on("connection", function(webSocket) { 

    // 1. Associate the socket with the remote address it came from. 
    var remoteAddress = webSocket._socket.remoteAddress; 
    var remotePort = webSocket._socket.remotePort; 
    var clientConnID = remoteAddress + ":" + remotePort; 

    var exists = clients[clientConnID] != null; 
    if (exists) { 
     console.log("socket server connection: associating new connection from %s with registered peer.", clientConnID); 
     clients[clientConnID].socket = webSocket; 
    } else { 
     console.log("socket server connection: associating new connection from %s with unregistered peer.", clientConnID); 
     clients[clientConnID] = { description: null, socket: webSocket }; 
    } 

    // 2. Hook up handlers for communication over this particular socket. 
    webSocket.on("message", function(data, flags) { 
     processMessage(webSocket, data, flags); 
    }); 

    webSocket.on("close", function() { 
     // Praise satin for closures!! 
     removePeer(clientConnID); 
    }); 

}); 

// Transduce the message and handle it accordingly. 
function processMessage(socket, data, flags) 
{ 
    var msg = JSON.parse(data); 
    if (!msg.signalType) { 

     var msg = createHostMsg(H2C_SIGNAL_TYPE_ERROR); 
     msg.errStr = "message_malformed"; 
     socket.send(JSON.stringify(msg)); 

    } else if (msg.signalType == C2H_SIGNAL_TYPE_REGISTER) { 
     handleRegistration(socket, msg); 
    } 
} 

клиент:

function initSignalChannel() 
{ 
    rtcPeer.channel = new WebSocket(location.origin.replace(/^http/, 'ws') + "/peers"); 
    rtcPeer.channel.onmessage = updateChannelMessage; 
    rtcPeer.channel.onopen = function(event) { 
     console.log("remote socket opened"); 
    } 
    rtcPeer.channel.onclose = function(event) { 
     console.log("host closed remote socket."); 
    } 
} 

function updateChannelMessage(event) { 

    var msgObj = JSON.parse(event.data); 

    if (!msgObj || !msgObj.signalType) { 

     console.log("updateChannelMessage: malformed response!! %o", msgObj); 

    } else if (msgObj.signalType == "welcome") { 

     console.log("updateChannelMessage: received welcome from host."); 
     handleWelcome(msgObj); 

    } else if (msgObj.signalType == "peer_joined") { 
     console.log("updateChannelMessage: received peer_joined from host."); 
     if (msgObj.peer.id == rtcPeer.description.id) { 
      console.log("updateChannelMessage: peer_joined: received notification that I've been added to the room. " + msgObj.peer.id); 
      console.log(msgObj); 
     } else { 
      console.log("updateChannelMessage: peer_joined: peer %s is now online.", msgObj.peer.id); 
      console.log(msgObj); 
      addRemotePeer(msgObj.peer); 
     } 
    } 

} 

function addRemotePeer(peerObj) 
{ 
    remotePeers[peerObj.id] = peerObj; 
    var ui = createPeerUIObj(peerObj); 
    $("#connectedPeerList").append(ui); 
} 

function createPeerUIObj(peerObj) 
{ 
    var ui = null; 
    if (peerObj) { 
     ui = $("<li></li>"); 
     var a = $("<a></a>"); 

     a.append("peer " + peerObj.id); 
     ui.append(a); 
     ui.click(function(event) { console.log("clicked");}); 
    } 

    return ui; 
} 

function handleWelcome(msgObj) 
{ 
    if (msgObj.id) { 

     console.log("updateChannelMessage: welcome: received id from host. " + msgObj.id); 
     console.log(msgObj); 
     rtcPeer.description.id = msgObj.id; 

     for (var p in msgObj.peers) { 
      addRemotePeer(msgObj.peers[p]); 
     } 

    } else { 
     console.log("updateChannelMessage: malformed response. no id."); 
    } 
} 
+1

Разместите node.js код и код клиента, мы не можем помочь вам без него –

+0

Это также стоит описывать, что инфраструктура для сервера (хостинг объекта, прокси, и т.д. ...), потому что некоторые не позволяйте долго работать, неактивные сокеты. – jfriend00

+0

Похоже, у вас установлен брандмауэр или прокси-сервер антивирусного фильтра, который не поддерживает веб-узлы. Но поскольку Марко и jfriend00 уже сказали, что знание вашего кода и вашей среды будет полезным. –

ответ

6

Спасибо за комментарии всех. Оказывается, что у jfriend00 был правильный ответ, я просто не понимал, что служба хостинга, которую я использовал, не позволит открывать соединение.

С ниже форум проводки, решение

вам нужно сделать ваши клиенты пинговать сервер периодически держать сокет жив.

Не самая идеальная ситуация, но действительно выполнимая. Спасибо, что указал мне в правильном направлении.

https://discussion.heroku.com/t/websocket-closes-after-60-seconds/333

Смежные вопросы