Correcting teacher:Guanhui
Correction status:qualified
Teacher's comments:可以!尽量贴出效果图!
websocket
通信服务的服务器, 像一个跟所有人保持通信的传声筒, 它可以接收来自客户端的消息, 也能主动给客户端发送消息. 而 http
通信, 服务器只能跟发送请求的客户端交互, 不能主动发送消息给客户端.websocket
链接跟 http
链接的区别: http
链接在客户端向服务器发送请求, 服务器返回响应后, 链接就会断开; websocket
链接在链接成功后, 可以持续通信, 链接会一直保持.
workerman
应用在服务器中的位置跟 Apache
, Nginx
相同. 即, web
服务器.
使用 workerman
创建使用 websocket
通信的应用服务器的一般步骤:
Worder
应用对象, 传入参数指定应用负责处理 websocket
通信. $ws_worker = new Worker("websocket://0.0.0.0:2000");
; 其中的 0.0.0.0:2000
表示接受任意IP客户端发送到服务器 2000
端口的链接请求.websocket
通信的系统进程数. $ws_worker->count = 4;
; $ws_worker->onMessage = function($connection, $data) {...}
; 其中参数 $connection
是发送数据的客户端与服务器的 websocket
链接; $data
是客户端发送过来的数据. $ws_worker->onClose = function($connection) {...}
; 其中参数 $connection
是即将关闭的 websocket
链接.Worker
应用.websocket
链接的 send(消息字符串)
向该链接的客户端发送消息数据. $connection->send('hello!');
Worder
对象的 connections
属性是当前与服务器保持通讯的 websocket
链接数组.客户端与提供 websocket
通信的服务器交互的一般步骤:
websocket
通信的链接: ws = new WebSocket("ws://127.0.0.1:2000");
. 其中 127.0.0.1
是客户端要与之创建 websocket
链接的服务器地址, 2000
是服务器监听链接和数据收发的端口号.cookie
中的 用户id
等. ws.onopen = function() {// 一般发送客户端的唯一标识给服务器存储 }
ws.onmessage = function(e) {// 收到服务器的消息了, 处理消息数据吧}
websocket
连接的 send(消息字符串)
方法向服务器发送数据.connections
属性数组, connections
属性保存有所有成功跟客户端创建链接的连接对象. 当某个客户端给服务器发送消息时, 服务器遍历 connections
中链接对象, 给连接对象的客户端发送消息, 即可实现群发. 代码
<?php
use Workerman\Worker;
require_once __DIR__ . '/workerman/Autoloader.php';
// 注意:这里与上个例子不同,使用的是websocket协议
$ws_worker = new Worker("websocket://0.0.0.0:2000");
// 启动4个进程对外提供服务
$ws_worker->count = 4;
// 当接收到客户端发来的消息时的处理方法
$ws_worker->onMessage = function($connection, $data)
{
// 发送消息的连接id
$message['from_id'] = $connection->id;
// 消息内容
$message['msg'] = $data
// 转成json字符串
$jsonStr = json_encode($message);
// 遍历当前所有的链接对象, 给连接对象对应的客户端发送数据
foreach($ws_worker->connection as $conn) {
$connection->send($jsonStr);
}
}
// 运行worker
Worker::runAll();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>"百度商桥"客户端</title>
<link rel="stylesheet" href="/static/plugin/layui/css/layui.css" media="all">
<script src="/static/plugin/layui/layui.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #fafafa;
}
.im {
width: 400px;
height: 520px;
background-color: wheat;
margin: 40px auto;
padding: 10px;
}
.im .history {
background-color: white;
border: 1px solid #aaa;
width: 100%;
height: 290px;
padding: 5px;
overflow-y: auto;
}
.im .inputing {
background-color: white;
border: 1px solid #aaa;
width: 100%;
height: 150px;
margin-top: 10px;
padding: 5px;
outline: none;
}
.im .btn-area {
width: 100%;
text-align: right;
margin-top: 10px;
}
.msg-box-friend {
padding: 10px;
width: 75%;
margin: 5px auto 0 5px;
background-color: lightblue;
border: 1px solid #ccc;
border-radius: 5px;
/* overflow-x: wordwrap; */
white-space:normal;
}
.msg-box-me {
padding: 10px;
width: 75%;
margin: 5px 5px 0 auto;
background-color: wheat;
border: 1px solid #ccc;
border-radius: 5px;
/* overflow-x: wordwrap; */
white-space:normal;
}
</style>
</head>
<body>
<div class="im">
<div class="history">
</div>
<!-- contenteditable="true", 这个div就可编辑了 -->
<div class="inputing" contenteditable="true">
</div>
<div class="btn-area">
<span class="layui-btn layui-btn-success" onclick="send()">发送</span>
</div>
</div>
</body>
<script>
layui.use(['layer'], function() {
layer = layui.layer;
});
// 假设服务端ip为127.0.0.1
ws = new WebSocket("ws://127.0.0.1:2000");
/* 当客户端连通服务器端的时候 */
ws.onopen = function() {
// ...
};
ws.onmessage = function(e) {
// alert("收到服务端的消息:" + e.data);
var receive = JSON.parse(e.data);
var str = "<div class='msg-box-friend'>"+receive.from_id+"说: "+receive.msg+"</div>";
$(str).appendTo('.history');
};
function send() {
// 消息框
var str = "<div class='msg-box-me'>我说: "+$('.inputing').html()+"</div>";
var data = {};
// 标识此次发送的数据是发送消息
data.type='msg';
// 标识是从客服端发的
data.group = 'admin'
// 标识私聊的对象id,0标识群发. DEL_客户连接时由系统随机分配客服小姐姐, 不需要手动指定了
// data.sendId = 0;
// 要发送的消息
data.msg = $('.inputing').html();
// 在消息历史中显示发送的消息
$(str).appendTo('.history');
// 发送JSON格式的数据
ws.send(JSON.stringify(data));
$('.inputing').html('');
}
</script>
</html>