2011-08-02 56 views
35

Tôi sẽ phát điên với socket.io! Tài liệu quá tệ, đơn giản là không đúng.Gửi tin nhắn đến khách hàng cụ thể với socket.io và hàng đợi tin nhắn rỗng

Tôi muốn gửi một phản hồi cho khách hàng cụ thể trên socket.io

phía máy chủ của tôi trông như thế này:

app.get('/upload', requiresLogin, function(request, response) { 
    response.render('upload/index.jade'); 
    io.sockets.on('connection', function (socket) { 
     console.log('SOCKET ID ' + socket.id); 
     io.sockets.socket(socket.id).emit('new', 'hello'); 
    }); 
}); 

và các mặt hàng khác trông như thế này:

$(document).ready(function() { 
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js'); 
    socket.on('new', function (data) { 
     console.log(socket.id); 
     console.log(data); 
     //$('#state').html(data.status); 
    }); 
}); 

nhưng khách hàng chỉ đơn giản là không có gì. Tôi đã thử gần như mọi thứ. Ai đó có thể cho tôi biết những gì tôi đang làm sai, xin vui lòng! :(

Trả lời

7

2 điều

1) Bạn thực sự nên đặt io.sockets.on(..) của bạn bên ngoài app/update tuyến đường của bạn để ngăn chặn thêm nhiều người nghe cho khách hàng.

2) io.sockets.socket (id); không nên sử dụng, cần phải có socket.emit('new', 'hello')

+0

không sao, đây cũng là vấn đề io.connect ('http: // localhost: 80/socket.io/socket.io.js'); nhưng khi tôi muốn gửi tin nhắn trong quá trình tải lên thì sao? sau đó tôi cần lưu trữ ID ứng dụng khách và sử dụng io.sockets.socket (socket.id) .emit ('new', 'hello'); hay không? –

+0

theo như tôi biết kết nối ổ cắm không bị ngắt kết nối trong khi tải lên tệp qua biểu mẫu. – pkyeck

+0

ổn tuyệt vời và câu hỏi cuối cùng. là nó có thể chết rỗng hàng đợi tin nhắn? khi tôi nhập lại quan điểm tôi nhận được tất cả các loại massage cũ ... –

52

để gửi tin nhắn đến một khách hàng cụ thể lưu mọi thông báo kết nối với máy chủ trong đối tượng.

var socketio = require('socket.io'); 
var clients = {}; 
var io = socketio.listen(app); 

io.sockets.on('connection', function (socket) { 
    clients[socket.id] = socket; 
}); 

sau đó bạn sau này có thể làm điều gì đó như thế này:

var socket = clients[sId]; 
socket.emit('show', {}); 
+0

không hoạt động. tôi đã thực hiện một thử nghiệm đơn giản: var soc; io.sockets.on ('kết nối', hàm (socket) { \t soc = socket; }); bên ngoài mọi tuyến đường. và trong chức năng tải lên của tôi, tôi đã sử dụng soc.emit ('news', 'bla') không có gì xảy ra .... –

+0

như đã nói trước đây: bạn không thể gửi sự kiện trong khi tải lên tệp. nhưng phương thức này hoạt động và bạn có thể gửi tin nhắn tới các máy khách cụ thể, khi bạn có id tương ứng. – pkyeck

+0

: -/xin lỗi tôi hiểu lầm bạn. vì vậy không có cách nào để kích hoạt một tin nhắn cho một khách hàng cụ thể từ một chức năng tuyến đường? –

2

Trước hết, bạn không thể sử dụng socket.id về phía khách hàng.

Và sau đó thay đổi dòng

var socket = io.connect('http://localhost:80/socket.io/socket.io.js');

để

var socket = io.connect('http://localhost:80/');

18

Một vài cách để gửi phản hồi cho một khách hàng cụ thể trên socket.io bao gồm:

  • Như đã nêu bởi p kyeck, lưu tất cả các khách hàng đến một đối tượng, vì vậy bạn có thể gửi tới những khách hàng cụ thể sau này trong xử lý tuyến đường của bạn, ví dụ:

    var sessionsConnections = {}; 
    sio.on('connection', function (socket) { 
        // do all the session stuff 
        sessionsConnections[socket.handshake.sessionID] = socket; 
    }); 
    
  • hay, sử dụng socket.io được xây dựng trong hỗ trợ cho phòng - đăng ký mỗi khách hàng đến một phòng trên kết nối và gửi qua phòng này trong thời hạn xử lý tuyến đường, ví dụ:

    sio.on('connection', function (socket) { 
        // do all the session stuff 
        socket.join(socket.handshake.sessionID); 
        // socket.io will leave the room upon disconnect 
    }); 
    
    app.get('/', function (req, res) { 
        sio.sockets.in(req.sessionID).send('Man, good to see you back!'); 
    }); 
    

Lời cảm ơn:

http://www.danielbaulig.de/socket-ioexpress/#comment-1158

Lưu ý rằng cả hai giải pháp ví dụ này giả định rằng socket.io và express được cấu hình để sử dụng cùng một phiên lưu trữ và do đó tham chiếu đến cùng một đối tượng phiên.Xem các liên kết bên trên và bên dưới để biết thêm chi tiết về việc đạt được điều này:

https://github.com/LearnBoost/socket.io/wiki/Authorizing

+0

Chỉ muốn nói rằng sử dụng id phiên làm phòng là một gợi ý tuyệt vời. Giúp tôi giải quyết một vấn đề tôi đã gặp phải, vì vậy cảm ơn :) –

+2

có vẻ như socket.io 1.0 đã được xây dựng để hỗ trợ cho phương pháp phòng trên mỗi socket: http://socket.io/docs/rooms-and-namespaces/ –

+0

Phòng nên chăm sóc phân cụm. Tiết kiệm ổ cắm trong bộ nhớ cục bộ như các câu trả lời khác có thể dẫn đến rò rỉ bộ nhớ và không thể mở rộng quy mô. – tsuz

5

Trong socket.io 1.0, đây là cách nó sẽ làm việc. Nó có thể làm việc cho các phiên bản thấp hơn, nhưng tôi không thể đảm bảo nó.

socket.to(socket_id_here).emit('new', 'hello'); 

Điều này hoạt động vì socket.io tự động thêm ổ cắm vào phòng có id của ổ cắm khi kết nối.

Ngoài ra, nếu bạn định nâng cấp lên phiên bản 1.0, có rất nhiều thay đổi đối với api, vì vậy đôi khi bạn sẽ phải thay đổi một số mã để làm cho nó hoạt động trong 1.0.

0

Tôi tin rằng io.sockets.socket đã bị xóa và đã xảy ra sự cố trong Socket.IO (https://github.com/socketio/socket.io/issues/1618).

Bạn có thể sử dụng io.sockets.connected [socket.id] và lưu trữ các socket.id để tham khảo với người sử dụng thông qua username:

var usernames = {}; 
usernames[username] = socket.id; 
// Sending the message 
io.sockets.connected[usernames[username]].emit(...); 

Tôi không nhìn thấy nó bất cứ nơi nào trên tài liệu vì vậy tôi có thể thấy cách điều này chưa được trả lời. Ngoài ra, nếu bạn không có bất kỳ tham chiếu nào thông qua tên người dùng, bạn có thể thử:

users[socket.id] = socket.id; 

để nhân đôi khóa và giá trị để dễ dàng truy cập.

Cũng có thể có cách khác bằng cách sử dụng io.clients như được mô tả bên dưới, nhưng tôi chưa sử dụng phương pháp đó.

GIẢI PHÁP KHÁC: Send message to specific client with socket.io and node.js

4

Các cách chính xác để làm điều này trong Socket.io 1.0 trở lên là:

io.to(users_socket_id).emit('new', 'hello'); 

Bạn cũng có thể thay thế một tên phòng cho 'users_socket_id' phát ra vào một ổ cắm cụ thể .io phòng.

0

Bạn đã thử sử dụng chưa?

var socket = io.connect('http://localhost:80/'); 
+0

Câu trả lời này đã được Shekhar đưa ra một vài câu trả lời –

0

tôi mệt mỏi với các phiên bản mới nhất của nút và socket.io dưới đây tôi đang đi để viết mã hoàn chỉnh

<ul id="messages"></ul> 
<form action=""> 
    <input id="id1" /><button>Send</button> 
</form> 
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script> 
<script src="http://code.jquery.com/jquery-1.11.1.js"></script> 
<script> 

    var io = io.connect(); 
    $('form').submit(function(){ 
    io.emit('drumevent', $('#id1').val()); 
    $('#id1').val(''); 
    return false; 
    }); 
    io.on('drumevent', function(msg){ 
    console.log(msg); 



    $('#messages').append($('<li></li>').text(msg.message+' quantity = '+msg.quantity)); 
    }); 
</script> 

mã phía máy chủ

var usernames = {};io.on('connection', function(socket){usernames["username"] = socket.id; 
socket.on('drumevent', function(msg){  
var socketId = socket.id;io.to(socketId).emit('drumevent', data); 
Các vấn đề liên quan