1

我刚刚设法使用 socket.io 连接到服务器脚本,所以我很高兴。我对我的脚本生成的奇怪行为不太满意:我在单击按钮时向服务器脚本发送一个发射,而服务器测试脚本向控制台日志发送回一条消息 6x。谷歌搜索这个问题描述会得到关于参差不齐、重复连接的想法,但我不认为就是这样。

无论如何,这是客户端 app.js:

var commentapp={
    init: function(){
        var commentapp=this;
        commentapp.btn_api=$('#btn_api'); 
        commentapp.btn_api.click(this.get_comment_data);        
    },
    get_comment_data: function(btn_event){
        var commentapp=this;

        console.log('trying to connect');
        commentapp.socket=io.connect('http://localhost:8080');

        commentapp.socket.on('connect', function() {
            commentapp.socket.emit('btn_api_call');
        });  //commentapp.socket.on 'connect',

        commentapp.socket.on('serverMessage', function(content){
            console.log(content);
            }
        ); //commentapp.socket.on('serverMessage'

    }

};

$(function() {
  commentapp.init();
});

服务器脚本如下:

var httpd = require("http").createServer(handler);
var io=require('/Users/user/Virtualenvs/node_modules/socket.io/lib/socket.io').listen(httpd);
var fs = require('fs');
var url = require("url");
var path = require("path");
var port = process.argv[2] || 8080;

httpd.listen(parseInt(port, 10));   

function handler (request, response) {

  var uri = url.parse(request.url).pathname,    
  filename = path.join(process.cwd(), uri);      

  console.log(uri);

  path.exists(filename, function(exists) {  
    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;   //these returns get you out of the function I think
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';  

    fs.readFile(filename, "binary", function(err, file) {       
      if(err) {        
        response.writeHead(500, {"Content-Type": "text/plain"});
        response.write(err + "\n");
        response.end();
        return;
      }

      response.writeHead(200);
      response.write(file, "binary");  //otherwise here's where the file gets finally served
      response.end();
    }); //fs.readFile

  }); //path.exists

      io.sockets.on('connection',function(socket) {
        socket.on('btn_api_call', function() {
            socket.emit('serverMessage', 'Server heard you.');
            });

      });

};              

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

这两个都是从https://github.com/accbel/nodejs-socketio-example和 Pedro Teixeira 的书中蚕食的。

因此,如果我单击生成'btn_api_call'emit 的按钮,控制台日志将显示“'服务器听到你了。'” 6x。希望这是一个容易纠正的菜鸟错误。

谢谢你的帮助!

4

1 回答 1

2

这可能是由于您在路由处理程序中注册了连接。

每次收到由该路由处理的请求时,代码都会为连接添加一个新的侦听器。

您的客户端可能有类似的问题 - 每次单击按钮时都连接。

将您的连接侦听器移到路由之外,如下所示:

function handler (request, response) {

  var uri = url.parse(request.url).pathname,    
  filename = path.join(process.cwd(), uri);      

  console.log(uri);

  path.exists(filename, function(exists) {  
    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;   //these returns get you out of the function I think
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';  

    fs.readFile(filename, "binary", function(err, file) {       
      if(err) {        
        response.writeHead(500, {"Content-Type": "text/plain"});
        response.write(err + "\n");
        response.end();
        return;
      }

      response.writeHead(200);
      response.write(file, "binary");  //otherwise here's where the file gets finally served
      response.end();
    }); //fs.readFile

  }); //path.exists
};

io.sockets.on('connection',function(socket) {
  socket.on('btn_api_call', function() {
    socket.emit('serverMessage', 'Server heard you.');
  });
});

在客户端将连接逻辑移动到 init - 类似于:

var commentapp={
    init: function(){
        var commentapp=this;
        commentapp.btn_api=$('#btn_api'); 
        commentapp.btn_api.click(this.get_comment_data);        

        console.log('trying to connect');
        commentapp.socket=io.connect('http://localhost:8080');

        commentapp.socket.on('connect', function() {
            commentapp.socket.emit('btn_api_call');
        });  //commentapp.socket.on 'connect',

        commentapp.socket.on('serverMessage', function(content){
            console.log(content);
            }
        ); //commentapp.socket.on('serverMessage'
    },
    get_comment_data: function(btn_event){
        var commentapp=this;

        commentapp.socket.emit('btn_api_call');
    }

};
于 2013-08-29T21:48:29.077 回答