Javascript 为什么我的websocket在几分钟后关闭?

Javascript 为什么我的websocket在几分钟后关闭?,javascript,node.js,websocket,Javascript,Node.js,Websocket,我在服务器端使用ws with node.js,在客户端使用常规WebSocket API。打开连接并来回发送消息几次都可以。但是插座总是在一两分钟后关闭。难道他们不应该坚持下去吗?我做错什么了吗 我的服务器是托管在heroku上的node.js。我刚刚使用foreman start(在本地运行服务器的heroku工具)再次在本地进行了测试,并且套接字根本没有意外关闭,因此可能是heroku的配置错误。无论如何,这里有一个相关的代码示例,为了简洁起见省略了一些函数 我正在OSX Yosemite

我在服务器端使用ws with node.js,在客户端使用常规WebSocket API。打开连接并来回发送消息几次都可以。但是插座总是在一两分钟后关闭。难道他们不应该坚持下去吗?我做错什么了吗

我的服务器是托管在heroku上的node.js。我刚刚使用
foreman start
(在本地运行服务器的heroku工具)再次在本地进行了测试,并且套接字根本没有意外关闭,因此可能是heroku的配置错误。无论如何,这里有一个相关的代码示例,为了简洁起见省略了一些函数

我正在OSX Yosemite上的Chrome上测试该应用程序,但在Windows7上的Chrome上,在生产环境下运行时也看到了同样的行为

服务器:

// 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);
    }
}
//客户端主机协议函数。移动到另一个文件,以便可以共享这些文件。
var C2H\u信号类型\u寄存器=“寄存器”;
var H2C_信号_WELCOME=“WELCOME”;
变量H2C\U信号类型错误=“错误”;
var H2C_信号类型_PEER_ADDED=“PEER_joined”;
变量H2C_信号类型_PEER_LEFT=“PEER_LEFT”;
//更新通道端点名称。
var UPDATE_ENDPOINT_PEERS=“/PEERS”;
//创建具有所有相关默认属性的信号消息。
//信号发送者应创建此对象,并在
//构建要发送给对等方的信号消息。
函数createHostMsg(类型)
{
var msg={signalType:type};
if(类型==H2C\U信号\U欢迎){
//因为我们要发送欢迎信息,所以我们需要提供一个列表
//当前连接的客户端的数目。
msg.peers={};
for(客户端中的var地址){
控制台日志(“addr”+addr);
var c=客户机[addr]。说明;
如果(c&c.id){
msg.peers[c.id]=c;
}
}
}
返回味精;
}
//需要模块。
var express=需要(“express”);
var http=require('http');
var bodyParser=require('body-parser');
var multer=需要('multer');
//跟踪连接的对等点。
var客户端={};
// 1.  配置应用程序上下文设置。
var-app=express();
应用程序启用(“信任代理”);
app.use(express.static(uu dirname+/public));
app.use(bodyParser.json());//解析json
app.use(bodyParser.urlencoded({extended:true}));//用于解析应用程序/x-www-form-urlencoded
app.use(multer());//用于解析多部分/表单数据
//a。配置http路由器。这些将处理来自应用程序的请求。
应用程序集('端口',(process.env.port | | 5000));
app.get('/app',peerApp);
app.get('/script/:name',publicScriptRouter);
// 2.  创建http服务器本身,将应用程序传递为请求处理程序。
//该应用程序将处理传入请求到不同服务器的路由和多路复用
//路由中间件处理程序。
var http=require('http');
var WebSocketServer=require(“ws”).Server
var httpServer=http.createServer(app);
httpServer.listen(app.get('port'));
// 3.  为所有套接字端点创建其中一个。
var wss=newwebsocketserver({server:httpServer,path:UPDATE\u ENDPOINT\u PEERS});
wss.on(“连接”,函数(webSocket){
//1.将套接字与其来源的远程地址关联。
var remoteAddress=webSocket.\u socket.remoteAddress;
var remotePort=webSocket.\u socket.remotePort;
var clientConnID=remoteAddress+“:”+remotePort;
var exists=clients[clientConnID]!=null;
如果(存在){
console.log(“套接字服务器连接:将来自%s的新连接与注册的对等方关联。”,clientConnID);
客户端[clientConnID].socket=webSocket;
}否则{
console.log(“套接字服务器连接:将来自%s的新连接与未注册的对等方关联。”,clientConnID);
客户端[clientConnID]={description:null,socket:webSocket};
}   
//2.通过该特定套接字连接用于通信的处理程序。
webSocket.on(“消息”,函数(数据、标志){
processMessage(webSocket、数据、标志);
});
webSocket.on(“关闭”,函数(){
//赞美缎子的闭合!!
removePeer(clientConnID);
});
});
//转换消息并相应地处理它。
函数processMessage(套接字、数据、标志)
{
var msg=JSON.parse(数据);
如果(!msg.signalType){
var msg=createHostMsg(H2C信号类型错误);
msg.errStr=“消息格式不正确”;
send(JSON.stringify(msg));
}else if(msg.signalType==C2H\U信号类型\U寄存器){
手柄注册(插座,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.");
    }
}
函数initSignalChannel()
{
rtcPeer.channel=newWebSocket(location.origin.replace(/^http/,'ws')+“/peers”);
rtcPeer.channel.onmessage=updateChannelMessage;
rtcPeer.channel.onopen=函数(事件){
日志(“远程套接字已打开”);
}
rtcPeer.channel.onclose=函数(事件){
log(“主机关闭远程套接字”);
}
}
函数更新通道消息(事件){
var msgObj=JSON.parse(event.data);
如果(!msgObj | |!msgObj.signalType){
log(“updateChannelMessage:格式错误的响应!!%o”,msgObj);
}else if(msgObj.signalType==“欢迎”){
log(“updateChannelMessage:receivewelcome from host.”);
handleWelcome(msgObj);
}else if(msgObj.signalType==“对等方已加入”){
log(“updateChannelMessage:receivedpeer_joined from host.”);
if(msgObj.peer.id==rtcPeer.description.id){
log(“updateChannelMessage:peer_joined:receivenotification,我已被添加到房间。”+msgObj.peer.id);
console.log(msgObj);
}否则{
log(“updateChannelMessage:peer_joined:peer%s现在在线。”,msgObj.peer.id);
console.log(msgObj);
addRemotePeer(msgObj.peer);
}
}
}
函数addRemotePeer(peerObj)
{
remotePeers[peerObj.id]=peerObj;
弗吉尼亚州