Fai*_*zan 3 sockets random chat node.js socket.io
我刚刚开始学习NodeJS和Socket.io ...直到现在我有这个演示代码,来自官方socket.io网站:
我能够获得连接的每个用户(套接字)的唯一客户端ID,我仍然想弄清楚,如何让我的代码在有人运行应用程序时只与1个随机用户连接.我只是想随便聊聊像http://www.omegle.com/
只有2个用户应该随机连接并相互聊天,直到他们重新运行应用程序,如果他们回来,他们应该与在线队列中的其他人联系.
有类似行为我需要做哪些改变?
到目前为止,这是我的代码:
专家的代码示例或指导对像我这样的菜鸟真的很有帮助.
更新:添加了客户端站点代码main.js
$(function() {
var FADE_TIME = 150; // ms
var TYPING_TIMER_LENGTH = 400; // ms
var COLORS = [
'#e21400', '#91580f', '#f8a700', '#f78b00',
'#58dc00', '#287b00', '#a8f07a', '#4ae8c4',
'#3b88eb', '#3824aa', '#a700ff', '#d300e7'
];
// Initialize variables
var $window = $(window);
var $usernameInput = $('.usernameInput'); // Input for username
var $messages = $('.messages'); // Messages area
var $inputMessage = $('.inputMessage'); // Input message input box
var $loginPage = $('.login.page'); // The login page
var $chatPage = $('.chat.page'); // The chatroom page
// Prompt for setting a username
var username;
var connected = false;
var typing = false;
var lastTypingTime;
var $currentInput = $usernameInput.focus();
//Own Global
var room = '';
var socket = io();
function addParticipantsMessage (data) {
var message = '';
if (data.numUsers === 1) {
// message += "there's 1 participant";
// Status Message
message += "Waiting to connect with someone";
} else {
// message += "there are " + data.numUsers + " participants";
//Status message update
message = "You are connected to a stranger! Say Hey!";
}
log(message);
}
// Sets the client's username
function setUsername () {
username = cleanInput($usernameInput.val().trim());
// If the username is valid
if (username) {
$loginPage.fadeOut();
$chatPage.show();
$loginPage.off('click');
$currentInput = $inputMessage.focus();
// Tell the server your username
socket.emit('add user', username);
// Own
socket.emit('login', {'username' : 'Faizan'});
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢
kec*_*cer 35
虽然我会关闭这个问题,因为它太模糊了,但我觉得有必要给你一些见解,因为我在过去几年中使用websockets进行了太多的工作(尽管socketio和nodejs并没有那么多).我想一些简单的指南和相关链接可以帮助你.首先,
您应该已经知道Socket.io是一个WebSocket实现.WebSockets(WS)允许服务器随时发送数据,只要连接仍然是打开的,而不是旧的方式:客户端查询一直询问,如果服务器上有更新.
你可以想象一个女人和一个男人在聚会结束时:" 谢谢你今晚,我很乐意很快重复一遍.你能告诉我你的号码吗? " - 老人问道." 呃,你知道什么,最好给我你的,我保证我会给你打电话! "如果那个女孩要给他打电话,他每天都会打电话几次询问她是否会去某个地方(而且她' d回复否).反过来说,只有当她想去,他才会打电话给他.他当然会.我有点沮丧,但你得到了照片.女人是服务员,男人是客户.
(绝对基本,你应该知道这个=>)当客户端连接到你的服务器时,他应该被提供一个html页面和一些javascript,它建立了与你的WS服务器的连接.在您发布的代码中,Express用作http服务器.查看此示例以了解如何为用户提供html&js.
在大多数教程中,您还会注意到名称空间和房间.这些用于将用户分成子类别.一个服务器可能包含多个命名空间(默认情况下只有一个),每个命名空间可能包含多个空间.您可能不需要打扰命名空间,一个就足够了.但是,您需要了解房间(稍后会详细介绍).
接下来,取自您的代码
io.on('connection', function (socket) {
Run Code Online (Sandbox Code Playgroud)
重要的是要知道,这里的套接字基本上代表一个连接的客户端(在一个命名空间中,但可能在多个房间中).你可以用它做各种各样的事情,最值得注意的是:
socket.on(event, handler(data))socket.emit(event, data)socket.broadcast.emit(event, data)socket.join(room),socket.leave(room)分别.你在代码中看到了numUsers的定义吗?这是一个与所有客户端共享的全局变量,因为nodejs是单线程的.在该示例中,它在一个事件处理程序内递增.认为我们可以使用类似的东西?YES.
我们可以定义全局变量,例如队列.或Q如果你想.重点是,它可以是用于存储套接字的数组,或者更确切地说是客户端,它们当前不在聊天室中.
在本节的最后,我想指出另一个显而易见的事情.
为io对象(WS服务器)上发生的'connection'事件io.on('connection', handler);定义事件处理程序.每次客户端连接到您的WS服务器时都会触发此操作(在您的情况下,通过在客户端浏览器中运行的javascript).方法的参数是socket,这是你应该为每个客户端添加事件监听器的方法(你已经在代码中做了,特别是处理事件'新消息','添加用户','打字','停止输入'并'断开').
这实际上取决于您希望应用程序的复杂程度.在我看来,最低限度是(注意你可以改变事件名称,但'断开'应保持'断开'):
事件名称 - >给出的数据
这只是一个粗略的草图.沿途有多个不同的十字路口,您走的路径主要取决于您对应用的想法.如果您想同时打开多个聊天,则需要进行一些修改.如果您想让两个以上的人连接到同一个聊天,也是如此.在这里,我将描述最简单的情况,一个聊天,一个人,没有注册.从你的帖子来看,可能你想要什么.可能是错的.
用户在其Web浏览器中打开您的页面.你为他们提供HTML和JavaScript.javascript将启动与websocket服务器的新连接.此外,此时应定义所需事件的处理程序.建立连接后,将会发生这种情况:
io.on('connection', handler)将被解雇.将只安装适用于新套接字的处理程序,此时不执行任何其他操作.
socket.on('connect', handler)将被解雇.客户端应该在某处存储用户名.如果没有,没问题.连接将存在很长一段时间.您可以socket.emit('login', {'username':name)在连接后随时调用(在下面的示例中,我设置变量已连接,默认为false,但一旦建立连接就会设置为true.)
从客户端发送登录事件后,服务器会将其注册并保存到某处.可能性是无穷无尽的,在这种情况下,我将创建将socket.id映射到用户名的全局字典.之后,用户套接字应与另一个套接字配对或添加到队列中.因此,如果队列为空,只需将套接字附加到全局变量(它不必是一个数组,因为我们将第一个可用的套接字配对在一起,但是你可能想要实现一些用户的历史记录,所以它们不会再次与同一个人联系).如果队列不为空,我们从Q中拉出一个套接字并将它们添加到同一个房间.房间名称可以是随机的或任何你想要的,我将使用(socket1.id +'#'+ socket2.id(如果你想在一次聊天中拥有更多用户,则必须更改).
在您添加它们之后,您需要通知他们他们的聊天已经开始并向他们发送其他同行的名字.您将发出"聊天开始"事件.
客户将捕获事件并打开新窗口.之后,每当用户键入内容并发送它时,客户端就会发送带有有效负载{'message':user_inserted_text}的事件"message".服务器将在.on('message'处理程序中捕获它并将其广播到房间.注意:
广播意味着向除了启动它的套接字之外的所有人发送消息.
注意:我现在对socketio代码感到困惑.看看这个并告诉我,如果socket.rooms是一个数组或一个对象(socket.rooms[room] = room;??为什么?)
为了避免处理这个不直接的代码,让我们创建另一个全局对象,rooms它将为我们存储房间名称.我们将在那里映射socket.id - > roomName.
所以当消息来时,我们可以通过电话获得房间的名称rooms[socket.id].然后我们广播这样的消息:
socket.broadcast.to(room).emit('message', data);
Run Code Online (Sandbox Code Playgroud)
当数据是我们从发送方接收,因此反对{"文":"一些不错的消息"}.然后,您的同伴将接收它(您不会)并显示它(您应该在发送时显示它).
所以聊天会持续一段时间,然后其中一个用户决定他要离开/与其他人聊天.他们将关闭窗口,客户端将发出事件'离开房间'.服务器将捕获它并将其/他的同伴断开连接发送给另一方.如果客户端断开连接,也会发生同样的情况.关闭所有内容后,将两个用户添加到队列(如果另一个已与服务器断开连接,则只添加一个).在我的代码中,我不会确保它们不会再次配对.这是OP代码(不能很难).
所以,如果你读到这一点,你应该得到一些实际的代码.虽然我说实际,但它实际上是未经测试的.但是你知道,它应该像这样工作.
var connected = false;
var username = 'Faizan';
var room = '';
var socket = io('http://localhost');
socket.on('connect', function (data) { // we are connected, should send our name
connected = true;
if (username) socket.emit('login', {'username' : username});
});
socket.on('chat start', function(data) {
room = data.room;
show_chat_window(data.name); // some method which will show chat window
});
socket.on('chat end', function(data) {
hide_chat_window(); // this will close chat window and alert user that the peer ended chat
socket.leave(room); // it's possible to leave from both server and client, hoever it is better to be done by the client in this case
room = '';
});
socket.on('disconnect', function(data) { // handle server/connection falling
console.log('Connection fell or your browser is closing.');
});
var send_message = function(text) { // method, which you will call when user hits enter in input field
if (connected) socket.emit('message', {'text': text});
};
var leave_chat = function() { // call this when user want to end current chat
if (connected) {
socket.emit('leave room');
socket.leave(room);
room = '';
}
};
Run Code Online (Sandbox Code Playgroud)
不包括初始需求和html/js服务,只包括全局定义和主要io处理程序.
var queue = []; // list of sockets waiting for peers
var rooms = {}; // map socket.id => room
var names = {}; // map socket.id => name
var allUsers = {}; // map socket.id => socket
var findPeerForLoneSocket = function(socket) {
// this is place for possibly some extensive logic
// which can involve preventing two people pairing multiple times
if (queue) {
// somebody is in queue, pair them!
var peer = queue.pop();
var room = socket.id + '#' + peer.id;
// join them both
peer.join(room);
socket.join(room);
// register rooms to their names
rooms[peer.id] = room;
rooms[socket.id] = room;
// exchange names between the two of them and start the chat
peer.emit('chat start', {'name': names[socket.id], 'room':room});
socket.emit('chat start', {'name': names[peer.id], 'room':room});
} else {
// queue is empty, add our lone socket
queue.push(socket);
}
}
io.on('connection', function (socket) {
console.log('User '+socket.id + ' connected');
socket.on('login', function (data) {
names[socket.id] = data.username;
allUsers[socket.id] = socket;
// now check if sb is in queue
findPeerForLoneSocket(socket);
});
socket.on('message', function (data) {
var room = rooms[socket.id];
socket.broadcast.to(room).emit('message', data);
});
socket.on('leave room', function () {
var room = rooms[socket.id];
socket.broadcast.to(room).emit('chat end');
var peerID = room.split('#');
peerID = peerID[0] === socket.id ? peerID[1] : peerID[0];
// add both current and peer to the queue
findPeerForLoneSocket(allUsers[peerID]);
findPeerForLoneSocket(socket);
});
socket.on('disconnect', function () {
var room = rooms[socket.id];
socket.broadcast.to(room).emit('chat end');
var peerID = room.split('#');
peerID = peerID[0] === socket.id ? peerID[1] : peerID[0];
// current socket left, add the other one to the queue
findPeerForLoneSocket(allUsers[peerID]);
});
});
Run Code Online (Sandbox Code Playgroud)
上面的代码到最后有点乱.它可以做得更好,我鼓励你做得比我做得更好.掌握了这些材料,逐步完成并尝试理解.我想我评论最多,如果不是全部的话.祝好运.
我甚至都不惊讶.在这里,阅读漫画
| 归档时间: |
|
| 查看次数: |
8102 次 |
| 最近记录: |