2017-06-22 50 views
2

我在我的cakephp3应用程序中使用socket.io向连接的客户端显示其处理请求的状态。带apache的Socket.io - 套接字客户端1 id刷新连接的客户端2

插座脚本(Server.js)

var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
var jsdom = require("jsdom"); 
const { JSDOM } = jsdom; 

var dom = new JSDOM(""); 
var $ = require("jquery")(dom.window); 

io.on('connection', function(socket){ 
    console.log('A user connected'); 

    socket.on('Event 1', function(data, fn){ 

    // Data received successfully!!! 
    fn(); 
    // Processing 
    sock.emit('Return 1', {data}); 
    }); 
    socket.on('disconnect', function(){ 
    console.log('A user disconnected'); 
    }); 
    socket.on('Event 2', function(data){ 
    // Processing 
    var uid = data['uid']; //adding same user socket 
    if(!sockets_uid[uid]){ 
     sockets_uid[uid] = []; 
    } 
    sockets_uid[uid].push(socket); 
    $.each(sockets_uid, function(i, sock){ 
     sock.emit('Return 2', res); 
    });     
}); 

http.listen(2105, function(){ 
    console.log('Started on 2105'); 
}); 

客户端的JavaScript(client.js)放在default.thtml中(CakePHP默认渲染布局)

var nodeToken = "<?= $this->request->session()->read('nodeToken');?>"; 
var socket = io('http://localhost/node', {secure: true, query: {token: nodeToken}}); 
socket.on('connect_error', function(){ 
    console.log('Unable to connect); 
}); 

当客户端通过http://localhost:2105连接到节点服务器时,工作流程按预期工作。

但在代码移植到生产中,我使用阿帕奇(v2.4.7)使用Proxy Passrewrite到任何请求转发到http://localhost/node掩盖的端口。 的Apache2配置

在连接经由的apache到节点,初始连接建立成功和客户端接收来自服务器节点的响应预期。由于套接字 - 客户端连接正在使用default.ctp编写,因此与每个页面上的节点服务器的连接刷新刷新或重定向到使用相同default.ctp布局的任何其他视图。

我面临的问题是,只要执行了某个操作(称为另一个视图ctp),父客户端就无法接收节点服务器推送给客户端的任何更新。

如果apache没有被使用,并且节点服务器与client.js中的端口直接连接,那么一切都按预期工作,所以我怀疑apache2 proxy pass配置中一定有问题。我已经启用了mod_proxymod_ws_proxy模块。

任何帮助将不胜感激。

回答

3

经过大量的搜索和浏览之后,我发现在页面重新加载或在我的情况下,default.ctp布局用于另一个视图渲染,套接字连接被非正常终止

所以,我通过保持控股3个阵列的解决了这个问题:

  • 用户=>套接字-IDS系统
  • 套接字-ID的=>插座,并
  • 所有活动插座

现在,当页面刷新/套接字断开时,我删除了旧的终止套接字并仅将事件发送到新套接字。

socket.on('disconnect', function(){ 
    var socket_id = socket.id; 
    var uid = uids_sockets[socket_id]; 
    delete sockets[socket_id]; 
    var temp_array = sockets_uid[uid]; 
    var index = temp_array.indexOf(socket_id); 
    temp_array.splice(index, 1); 
    sockets_uid[uid] = temp_array; 
    }); 

此外,在客户端,我发射插槽上的启动事件连接事件,因此建立新的连接后,该事件被新插座重新注册。

如果直接建立与节点的连接而不使用Apache Proxy-pass中间件,则不需要所有配置。