websockt聊天

服务端

<?php
use workerman\Worker;
require dirname(__DIR__).'\Autoloader.php';
// 心跳间隔25秒
// define('HEARTBEAT_TIME', 25);


// 创建一个Worker监听9001端口,不使用任何应用层协议
$ws = new Worker("websocket://172.18.10.179:9001");


// 启动4个进程对外提供服务
$ws->count = 1;


// 用来保存uid到connection的映射(uid是用户id或者客户端唯一标识)
$worker->uidConnections = array();
$worker->usernames = array();




// 当客户端发来数据时
$ws->onMessage = function($connection, $data)
{
$getMsg = json_decode($data,true); //传递参数
//发送消息类型 login all toid
$type = isset($getMsg['type'])?$getMsg['type']:"";
$uid = isset($getMsg['username'])?$getMsg['username']:""; //formid
$message =isset($getMsg['message'])? $getMsg['message']:""; //msg
$connection->lastMessageTime = time(); //time
global $worker;

// 登录
if($type == "login")
{
if(!isset($connection->uid))
{
$connection->uid = $uid;
$worker->uidConnections[$uid] = $connection;
$worker->usernames[$uid] = $uid;
}
$result = array(
'msg' => "欢迎".$uid."进入聊天室!",
'data' => $worker->usernames
);
broadcast(json_encode($result));
} else if($type == "all") { // 广播
$result = array(
'msg' => $connection->uid."对大家说:".$message,
);
var_dump($result);
broadcast(json_encode($result));
} else { // 给特定uid发送
sendMessageByUid($connection->uid, $type, $message); 
}

};


$ws->onClose = function($connection){
global $worker;
    if(isset($connection->uid))
    {
        unset($worker->uidConnections[$connection->uid]);
        unset($worker->usernames[$connection->uid]);
    }
};


// 向所有验证的用户推送数据
function broadcast($message)
{
   global $worker;
   if(count($worker->uidConnections) != 0)
   {
  foreach($worker->uidConnections as $connection)
  {
       $connection->send($message);
  }
   }
}


// 针对uid推送数据
function sendMessageByUid($fromid, $tid, $message)
{
    global $worker;
    if(isset($worker->uidConnections[$tid]))
    {
    $selfconnection = $worker->uidConnections[$fromid];
        $connection = $worker->uidConnections[$tid];
        $result = array(
'msg' => $fromid."对".$tid."说:".$message,
);
        $connection->send(json_encode($result));
        $selfconnection->send(json_encode($result));
    }
}


$worker->onClose = function($connection)
{
global $worker;
    unset($worker->uidConnections[$connection->uid]);
};




// 运行worker
Worker::runAll();


客户端登录

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<div style="margin-top:20%;margin-left:30%;">
<form action="client.php" method="post">
请输入用户名:<br>
<input type="text" name="username">
<input type="submit">
</form>
</div>
</body>
</html>


客户端聊天

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>client</title>
<script type="text/javascript" src="jquery.js"></script>
</head>
<style>
#main{width:800px;height:600px;margin:auto;padding:auto}
#left{width:600px;height:600px;float:left}
#txtcontent{width:600px;height: 400px;border: 1px solid gray;overflow: scroll;}
#right{
width:180px;height:600px;background:#EEEEEE;float:right;padding:9px;
}
#right li {
   display: list-item;
   text-align: -webkit-match-parent;
}
textarea{width: 600px;height: 100px}
</style>


<script>
var ws;
var username = "<?php echo $_POST['username'];?>";
var target = "ws://172.18.10.179:9001";
// 连接服务器
if('WebSocket' in window){
ws = new WebSocket(target);
}else if('MozWebSocket' in window){
ws = new MozWebSocket(target);
}else{
alert("No support");
}


// 创建连接
ws.onopen = function(){
var login_data = '{"type":"login","username":"'+username.replace(/"/g, '\\"')+'"}';
ws.send(login_data);
};


// 发送消息
function sendmsg(){
var msg = $("#txtmsg").val(); //消息内容
var toid = $("#listuers").val(); //到送到谁
var msg_data = '{"type":"'+toid+'","message":"'+msg.replace(/"/g, '\\"')+'"}';
$("#txtmsg").val("");
ws.send(msg_data);
}


// 接收消息
ws.onmessage=function(e){
var getMsg = eval('(' + e.data + ')');
if(undefined != getMsg.msg)
{
var msg = getMsg.msg;
       $("#txtcontent").append("<p>"+msg+"</p>");
}
if(undefined != getMsg.data)
{
var data = getMsg.data;
var list = "";
var listuers = "<option value='all'>所有用户</option>";
for(var i in data){
list += "<li>"+data[i]+"</li>";
listuers += "<option value="+data[i]+">"+data[i]+"</option>";
};
$("#list").html("");$("#list").append(list);
$("#listuers").html("");$("#listuers").append(listuers);
}
};
// 关闭链接
ws.close=function(){};
</script>


<body>
<?php
if(!isset($_POST['username']))
{
header("Location:login.php");
}
?>
<div id="main">
<div id="left">
<div id="txtcontent">
</div><br>
所有用户:<select id="listuers"></select><br><br>
        <textarea style="" id="txtmsg"></textarea> <br>
        <button onclick="sendmsg()">发送消息</button>
    </div>
<div id="right" >
<h4 style="size:4px;">在线用户</h4>
<ul id="list"></ul>
</div>
</div>
</body>


</html>

### 使用 WebSocket 实现聊天功能 #### 创建 WebSocket 连接 为了实现基于 WebSocket 的聊天应用,在客户端可以通过 JavaScript 中的 `WebSocket` API 来创建一个新的 WebSocket 连接: ```javascript let webSocket = new WebSocket('ws://example.com/socketserver'); ``` 这里,URL 应该指向服务器端监听 WebSocket 请求的服务地址[^1]。 #### 处理连接事件 一旦建立了 WebSocket 对象实例,则可以为其绑定各种事件处理器来响应不同的生命周期阶段以及数据接收情况: - **open**: 当成功建立连接时触发; - **message**: 收到消息时调用; - **error**: 发生错误时执行; - **close**: 断开连接时激活。 ```javascript webSocket.onopen = function(event) { console.log("Connection opened", event); }; webSocket.onmessage = function(event) { console.log("Message received:", event.data); }; webSocket.onerror = function(error) { console.error("Error occurred:", error); }; webSocket.onclose = function() { console.log("Connection closed"); }; ``` 这些回调函数允许开发者针对每种情形定义特定的行为逻辑。 #### 发送与接收消息 当需要向服务器发送信息时,只需调用 `send()` 方法即可传递字符串形式的数据给对方;而在收到回复之后则会自动触发上面提到过的 `onmessage` 回调来进行进一步处理。 ```javascript // 向服务器发送一条消息 function sendMessage(messageText) { if (webSocket.readyState === WebSocket.OPEN) { webSocket.send(JSON.stringify({ type: "chat", content: messageText })); } else { alert("WebSocket connection not established, readyState: " + webSocket.readyState); } } ``` 对于更复杂的应用场景来说,可能还需要考虑诸如身份验证、断线重连机制等问题。不过以上就是最基础版本下的 WebSocket 聊天室构建方式概述[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值