Nodejs中socket.io可以点对点么?求思路

Nodejs中socket.io可以点对点么?求思路

19 回复

Node.js 中 Socket.IO 可以实现点对点通信吗?

Socket.IO 是一个流行的实时通信库,用于在浏览器和服务器之间进行双向通信。尽管 Socket.IO 主要设计为允许客户端和服务器之间的广播消息,但也可以通过一些技巧来实现点对点(P2P)通信。

点对点通信的基本思路

  1. 使用房间机制Socket.IO 提供了一个房间的概念,可以将客户端分配到特定的房间中。服务器可以通过房间名将消息发送给特定的一组客户端。
  2. 直接连接Socket.IO 默认情况下不支持直接点对点连接,但你可以利用房间机制来模拟这一点。

示例代码

以下是一个简单的示例,展示如何使用 Socket.IO 实现点对点通信:

// 服务器端代码 (server.js)
const io = require('socket.io')(3000, {
    cors: {
        origin: '*',
    }
});

io.on('connection', (socket) => {
    console.log('New client connected');

    socket.on('joinRoom', (roomName) => {
        socket.join(roomName);
        console.log(`Client joined room ${roomName}`);
    });

    socket.on('sendToRoom', ({ roomName, message }) => {
        io.to(roomName).emit('message', message);
    });

    socket.on('disconnect', () => {
        console.log('Client disconnected');
    });
});
// 客户端代码 (client.js)
const socket = io('http://localhost:3000');

socket.on('connect', () => {
    console.log('Connected to server');
});

socket.emit('joinRoom', 'room1');

socket.on('message', (message) => {
    console.log(`Message from room1: ${message}`);
});

document.getElementById('sendButton').addEventListener('click', () => {
    const message = document.getElementById('messageInput').value;
    socket.emit('sendToRoom', { roomName: 'room1', message });
});

解释

  1. 服务器端

    • 当客户端连接时,监听 joinRoom 事件,并将其加入指定的房间。
    • 监听 sendToRoom 事件,将消息广播到指定的房间。
  2. 客户端

    • 连接服务器后,发送 joinRoom 事件加入指定的房间。
    • 监听 message 事件,接收来自房间的消息。
    • 发送按钮点击时,发送 sendToRoom 事件,将消息发送到指定的房间。

通过这种方式,你可以在不同的客户端之间实现点对点通信。虽然不是真正的 P2P 连接,但这种机制可以有效地模拟点对点通信的效果。


你是指2端都是client?

间接的靠服务器转发的方式应该可以吧,直接的肯定不行

显然不行

不知道有没有别的现成模块可以用, 不然只能从 socket.join('room') 做文章了

用服务端做转发就行了,比如a、b这样通信: 创建socketMap对象用来记录对应socket,当客户端a、b连接时:

socketMap['a'] = socketA;
socketMap['b'] = socketB;

客户端a发消息给b:

socketMap['b'].emit(...);

这个方法想过。但是当用户数量多的时候不知道这种方式可行不。

socket.io也需要运行在浏览器中,怎么可能p2p?

貌似html5将来真的可以做到peer to peer

参见问题: http://stackoverflow.com/questions/1032006/will-html5-allow-web-apps-to-make-peer-to-peer-http-connections

但我不知道进一步的细节。

P2P必须UDP。不是socket.io的责任。

囧了。。。这还不如给两个人单独开个房间呢。

socket.join('room_ab');
io.sockets.in('room_ab').emit('msg', 'hello')

看到个模块 chat.io , 基本上把 socket.io 封装了一遍, 加了发送到指定用户的方法 https://github.com/DanielBaulig/chat.io https://github.com/DanielBaulig/chat.io/blob/master/package.json

这个chat.io 封装了socket.io的一些方法特别是对指定用户的封装对P2P的聊天实现比较方便

  • socket.io不能点对点
  • 消息都已服务器为中心转发
  • 在服务端保存一个用户的所有client列表,如{userId1:[client1,client2],userId2:[client1,client2]}
  • 客户端发送时指明目的用户(如以userId标识,权限、安全之类的另作验证即可)
  • 服务器查找目的用户所有client,emit出去即可

在Node.js中使用Socket.IO进行点对点通信是可行的。Socket.IO本身并不直接支持点对点(P2P)通信,但可以通过一些技巧实现。通常的做法是通过服务器作为中介来建立两个客户端之间的连接。

思路

  1. 服务器作为中介

    • 所有的客户端都连接到服务器。
    • 服务器将客户端的消息转发给目标客户端。
    • 客户端A向服务器发送消息时,服务器识别并转发给客户端B。
  2. 房间机制

    • 使用Socket.IO的房间机制来组织客户端。
    • 将两个客户端分配到同一个房间,这样它们可以直接在房间内通信。

示例代码

服务器端代码

const io = require('socket.io')(server);

io.on('connection', (socket) => {
    console.log('a user connected');

    socket.on('joinRoom', (roomName) => {
        socket.join(roomName);
        console.log(`User joined room ${roomName}`);
    });

    socket.on('message', (data) => {
        const { room, message } = data;
        io.to(room).emit('message', message);
    });

    socket.on('disconnect', () => {
        console.log('user disconnected');
    });
});

客户端A代码

<script src="/socket.io/socket.io.js"></script>
<script>
    const socket = io();

    // 连接到服务器
    socket.emit('joinRoom', 'private-room-A');

    // 发送消息到服务器
    function sendMessage(message) {
        socket.emit('message', { room: 'private-room-A', message });
    }
</script>

客户端B代码

<script src="/socket.io/socket.io.js"></script>
<script>
    const socket = io();

    // 连接到服务器
    socket.emit('joinRoom', 'private-room-A');

    // 监听消息
    socket.on('message', (message) => {
        console.log('Received:', message);
    });
</script>

解释

  • 在服务器端,我们创建了一个Socket.IO实例,并监听客户端的连接。
  • 当客户端连接后,它会加入一个特定的房间(例如private-room-A)。
  • 客户端A向服务器发送消息时,服务器会将消息广播给同一房间内的所有客户端(包括客户端B)。
  • 客户端B接收到消息后,在控制台中显示出来。

这种方法利用了Socket.IO的房间机制,使得客户端可以在服务器的帮助下间接实现点对点通信。

回到顶部