一瓷炮、什么是websocket泪漂?
websocket協(xié)議是基于TCP協(xié)議的一種新的持久化網(wǎng)絡(luò)通信協(xié)議咧七。通過(guò)一次瀏覽器請(qǐng)求衰齐、服務(wù)器響應(yīng)(一次握手)搭建出一條網(wǎng)絡(luò)雙通道,實(shí)現(xiàn)服務(wù)器主動(dòng)推送信息給瀏覽器继阻。
二耻涛、swoole的安裝
http://www.swoole.com
我直接在服務(wù)器上安裝的废酷。。抹缕。
三澈蟆、server.php(聊天室服務(wù)端)
<?php
//結(jié)合redis使用
$redis = new redis();
$result = $redis->connect("127.0.0.1", 6379);
$server = new swoole_websocket_server("0.0.0.0", "端口號(hào)");
$server->on('open', function (swoole_websocket_server $server, $request) {
global $redis;
$nfd = $request->fd;
echo "客戶端{(lán)$nfd}成功接入\n";
$redis->hset("User",$nfd,$nfd);//將客戶端id存入redis
$users = $redis->hvals("User");
});
$server->on('message', function (swoole_websocket_server $server, $frame) {
global $redis;
$data = $frame->data;//客戶端發(fā)送的信息
$fd = $frame->fd;//消息發(fā)送id
//類型判斷
$str = substr($data,0,8);
if($str == '{"name":'){
//登錄
$data = json_decode($data);
echo $fd.$data->name."登錄"."<br>";
$redis->hset("name",$fd,$data->name);//保存客戶端昵稱
$redis->hset("email",$fd,$data->email);//保存客戶端郵箱
$users = $redis->hvals("User");//取回所有用戶
foreach ($users as $u)
{
//對(duì)所有用戶發(fā)送消息
$server->push($u ,'0@1@4@3'.$redis->hGet('name',$fd));
}
}else{
//發(fā)送消息
echo $fd."發(fā)送消息:".$data;
$users = $redis->hvals("User");//取回所有用戶
foreach ($users as $u)
{
//對(duì)所有用戶發(fā)送消息
$server->push($u ,$redis->hGet('name',$fd).'說(shuō):'.$data);
}
}
});
$server->on('close', function ($ser, $fd) {
global $redis;
//清除用戶信息緩存
$redis->hdel("User",$fd);
$redis->hdel("name",$fd);
$redis->hdel("email",$fd);
$users = $redis->hvals("User");
var_dump($users);
echo "client {$fd} closed\n";
//$redis->flushAll();
});
$server->start();
?>
四、client.php(聊天室客戶端)
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<style>
#top{
width: 60%;
height: 50px;
text-align: left;
margin: 0 auto;
margin-top: 50px;
background-color: #3c3c3c;
}
#room{
width: 60%;
height: 500px;
text-align: center;
margin: 0 auto;
border: 1px solid ;
}
#left{
width: 25%;
float: left;
text-align: center;
margin: 30px;
border: 1px solid #ccc;
background-color: #E8E8D0;
}
#right{
width: 60%;
height: 90%;
float: right;
text-align: left;
margin: 30px 30px 20px 20px;
background-color: #F0F0F0;
}
#chat{
width: 100%;
height: 90%;
margin-left: 10px;
}
#submit1{
width: 100%;
height: 50px;
padding-bottom: 10px;
margin-top: 15px;
}
#submit2{
width: 100%;
height: 50px;
padding-bottom: 10px;
margin-top: 15px;
}
</style>
<script type="text/javascript">
if(window.WebSocket){
var webSocket = new WebSocket("ws://服務(wù)端ip:端口號(hào)");
webSocket.onopen = function (event) {
//webSocket.send("Hello,WebSocket!");
};
webSocket.onmessage = function (event) {
var content = document.getElementById('chat');
var left = document.getElementById('left');
if(event.data instanceof Blob) {
var img = document.createElement("img");
img.src = window.URL.createObjectURL(event.data);
content.appendChild(img);
}else {
var str = event.data.substring(0,7);
if(str == '0@1@4@3'){
//登錄
var name = event.data.substring(7,event.data.length);
left.innerHTML = left.innerHTML.concat('<p style="margin-left:0px;height:20px;line-height:20px;">'+name+'</p>');
}else{
//發(fā)送消息
content.innerHTML = content.innerHTML.concat('<p style="margin-left:20px;height:20px;line-height:20px;">'+event.data+'</p>');
}
}
};
//登錄
var login = function () {
var name = document.getElementById('name').value;
var email = document.getElementById('email').value;
if(name == ''){
alert('請(qǐng)輸入昵稱');
}else if(email == ''){
alert('請(qǐng)輸入郵箱');
}else{
var arr = new Array();
arr['name'] = name;
arr['email'] = email;
var a = '{"name":"'+name+'","email":"'+email+'"}';
webSocket.send(a);
document.getElementById('submit1').style.display = 'none';
document.getElementById('submit2').style.display = '';
}
}
//發(fā)送信息
var sendMessage = function(){
var data = document.getElementById('message').value;
if(data == ''){
alert('消息不能為空');
}else{
webSocket.send(data);
document.getElementById('message').value = '';
}
}
}else{
console.log("您的瀏覽器不支持WebSocket");
}
</script>
</head>
<body>
<div id="top">
<p style="line-height: 50px;margin-left: 20px;color: white">聊天室測(cè)試——swoole</p>
</div>
<div id="room">
<div id="left">
<span style="color: red;border-bottom:1px dashed red;overflow-y:auto;">在線用戶</span>
</div>
<?php
if(app\helpers\Isphone::is_mobile_request()) {
?>
<div id="right" style="height: 70%;width: 50%">
<div id="chat" style="overflow-y:auto;">
<p style="text-align: center">歡迎進(jìn)入聊天室卓研!</p>
</div>
<div id="submit1">
<input type="text" id="name" name="name" placeholder="昵稱" style="width: 120px"/>
<input type="text" id="email" name="email" placeholder="郵箱" style="width: 120px"/>
<button onclick="login()">登錄</button>
</div>
<div id="submit2" style="display: none;">
<input type="text" id="message" style="width: 70%">
<button onclick="sendMessage()" style="height:25px;width:75px;">發(fā)送</button>
</div>
</div>
<?php
}else {
?>
<div id="right">
<div id="chat" style="overflow-y:auto;">
<p style="text-align: center">歡迎進(jìn)入聊天室趴俘!</p>
</div>
<div id="submit1">
<input type="text" id="name" name="name" placeholder="昵稱"/>
<input type="text" id="email" name="email" placeholder="郵箱"/>
<button onclick="login()">登錄</button>
</div>
<div id="submit2" style="display: none;">
<input type="text" id="message" style="width: 70%">
<button onclick="sendMessage()" style="height:25px;width:75px;">發(fā)送</button>
</div>
</div>
<?php
}
?>
</div>
</body>
</html>
五、學(xué)習(xí)總結(jié)
初次接觸到網(wǎng)絡(luò)協(xié)議發(fā)現(xiàn)這里還需要自己更深入全面的學(xué)習(xí)和了解奏赘。
在消息推送上websocket相比較于http更方便快捷寥闪,避免了瀏覽器無(wú)時(shí)無(wú)刻的請(qǐng)求服務(wù)器,由被動(dòng)變主動(dòng)磨淌。
linux命令:
nohup command &
用途:命令不掛斷疲憋、后臺(tái)運(yùn)行。
中止nohup命令:ps -ef | grep command
kill -9 pid
聊天室弊端:
1.頁(yè)面過(guò)于簡(jiǎn)陋伦糯、用戶下線沒(méi)有提示柜某。
2.服務(wù)端沒(méi)有涉及到數(shù)據(jù)庫(kù)操作嗽元,無(wú)法查看歷史聊天記錄敛纲。