2013-10-21 43 views
0

我在我的网站上有一个正在运行的聊天应用程序。它使用websockets,php来实现,并且工作正常。问题是,只要我向单个用户发送消息,它就会将该消息广播给当前连接到我的网站的所有用户。如果有人能够告诉我如何在有人连接到我们的应用程序时获取每个用户的唯一ID,那将非常有帮助。如果我可以获取当前登录的聊天用户的用户名,这将解决我的问题,但当用户连接(打开websocket的状态)时,我无法检索该用户名。我可以在建立连接时获取用户标识,但在连接发生之前需要用户标识。当连接发生时,它以串行方式(1,2,3 ..,n)为连接的用户分配自己的ID。Websockets群聊特定用户

<?php 
// prevent the server from timing out 
set_time_limit(0); 

// include the web sockets server script (the server is started at the far bottom of this file) 
require 'class.PHPWebSocket.php'; 

// when a client sends data to the server 
function wsOnMessage($clientID, $message, $messageLength, $binary) { 
global $Server; 
$ip = long2ip($Server->wsClients[$clientID][6]); 

// check if message length is 0 
if ($messageLength == 0) { 
    $Server->wsClose($clientID); 
    return; 
} 

//Send the message to everyone but the person who said it 
foreach ($Server->wsClients as $id => $client) 
    if ($id != $clientID) 
     $Server->wsSend($id, "Visitor $clientID ($ip) said "$message""); 
} 

// when a client connects 
function wsOnOpen($clientID) 
{ 
global $Server; 
$ip = long2ip($Server->wsClients[$clientID][6]); 

$Server->log("$ip ($clientID) has connected."); 

//Send a join notice to everyone but the person who joined 
foreach ($Server->wsClients as $id => $client) 
    if ($id != $clientID) 
     $Server->wsSend($id, "Visitor $clientID ($ip) has joined the room."); 
} 

// when a client closes or lost connection 
function wsOnClose($clientID, $status) { 
global $Server; 
$ip = long2ip($Server->wsClients[$clientID][6]); 

$Server->log("$ip ($clientID) has disconnected."); 

//Send a user left notice to everyone in the room 
foreach ($Server->wsClients as $id => $client) 
    $Server->wsSend($id, "Visitor $clientID ($ip) has left the room."); 
} 

// start the server 
$Server = new PHPWebSocket(); 
$Server->bind('message', 'wsOnMessage'); 
$Server->bind('open', 'wsOnOpen'); 
$Server->bind('close', 'wsOnClose'); 
// for other computers to connect, you will probably need to change this to your LAN IP or external IP, 
// alternatively use: gethostbyaddr(gethostbyname($_SERVER['SERVER_NAME'])) 
$Server->wsStartServer('127.0.0.1', 9300); 

?> 

HTML

<!doctype html> 
<html> 
<head> 
<meta charset='UTF-8' /> 
<style> 
    input, textarea {border:1px solid #CCC;margin:0px;padding:0px} 

    #body {max-width:800px;margin:auto} 
    #log {width:100%;height:400px} 
    #message {width:100%;line-height:20px} 
</style> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
<script src="fancywebsocket.js"></script> 
<script> 
    var Server; 

    function log(text) { 
     $log = $('#log'); 
     //Add text to log 
     $log.append(($log.val()?"n":'')+text); 
     //Autoscroll 
     $log[0].scrollTop = $log[0].scrollHeight - $log[0].clientHeight; 
    } 

    function send(text) { 
     Server.send('message', text); 
    } 

    $(document).ready(function() { 
     log('Connecting...'); 
     Server = new FancyWebSocket('ws://127.0.0.1:9300'); 

     $('#message').keypress(function(e) { 
      if (e.keyCode == 13 && this.value) { 
       log('You: ' + this.value); 
       send(this.value); 
       $(this).val(''); 
      } 
     }); 

     //Let the user know we're connected 
     Server.bind('open', function() { 
      log("Connected."); 
     }); 

     //OH NOES! Disconnection occurred. 
     Server.bind('close', function(data) { 
      log("Disconnected."); 
     }); 

     //Log any messages sent from server 
     Server.bind('message', function(payload) { 
      log(payload); 
     }); 

     Server.connect(); 
    }); 
</script> 
</head> 

<body> 
<div id='body'> 
    <textarea id='log' name='log' readonly='readonly'></textarea><br/> 
    <input type='text' id='message' name='message' /> 
</div> 
</body> 

</html> 

回答

1
  1. 在服务器中创建一个temp_users阵列。

  2. 当每个客户端连接时,创建一个唯一的ID并将新的套接字和唯一ID添加到该阵列,然后将该ID发送到客户端,并标头指示这是系统消息。

  3. 在客户端代码中,让客户端从系统消息中检索唯一标识。撰写带有唯一ID和客户端用户名的邮件,然后将其发送回服务器。

  4. 将接收到的用户名映射到temp_users数组中的对应ID。您现在可以识别特定用户并使用映射到其用户名的套接字向他们发送消息。