客户端html页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./jquery-3.2.1.min.js"></script>
<script src="./jquery.qqFace.js"></script>
<style>
li{
list-style: none;
}
</style>
</head>
<body>
<div>
<div class="left" style="float: left;border: 1px solid red;width: 70%;height: 600px">
<div style="height: 450px;">
<ul id="message">
<li style="text-align: right;">测试</li>
<li style="text-align: right;">聊天室</li>
</ul>
</div>
<hr>
<div class="com_form">
<div style="display: none;">
<textarea class="input" name="saytext" id="saytext" cols="120%" rows="5" placeholder="发送内容" style="min-height: 50px;min-width: 600px;"></textarea>
</div>
<select name="send_user" id=""></select><span class="emotion">表情</span><a href="javascript:;" id="history_list">查看聊天记录</a>
<textarea class="input" id="content" cols="120%" rows="5" placeholder="发送内容" style="min-height: 50px;min-width: 600px;"></textarea>
<button id="sendMessage">发送</button>
</div>
</div>
<div class="right" style="float: right;border: 1px solid blue;width: 29%;height: 600px">
<ul id="user_list">
</ul>
<ul id="history_msg">
</ul>
</div>
</div>
</body>
</html>
<script>
/*$('.emotion').qqFace({
id : 'facebox', //表情盒子的ID
assign:'saytext', //给那个控件赋值
path:'face/', //表情存放的路径
});*/
$(".emotion").click(function(){
$(this).qqFace({
id : 'facebox', //表情盒子的ID
assign:'saytext', //给那个控件赋值
path:'face/', //表情存放的路径
})
var str = $("#saytext").val();
$("#content").html(str);
});
var user_name = '';
var password = '123456';
function showprompt(){
while( user_name == '' ){
user_name = prompt('请输入你的用户名');
}
while( password == '' ){
password = prompt('请输入你的密码');
}
// type = 1 标示发送的是登录的数据
var data = '{"type":1,"user_name":"'+user_name+'","password":"'+password+'"}';
console.log( '发送给服务端数据:'+ data );
websocket.send( data );
console.log(123)
}
$('#sendMessage').click(function(){
sendMessage()
})
function sendMessage(){
var content = $('#content').val();
var user_id = $('[name=send_user]').val();
console.log(user_id);
$('#content').val('')
// content.replace('\r\n',"<br/>");
content=content.replace(/\r/g," ");
content=content.replace(/\n/g,"<br />");
if( user_id != -1 ){
var json ='{"type":2,"user_name":"'+user_name+'","message":"'+content+'","send_to":'+user_id+'}';
}else{
var json ='{"type":2,"user_name":"'+user_name+'","message":"'+content+'","send_to":"all"}';
}
console.log(json);
websocket.send(json);
}
$('#history_list').click(function(){
sendHistory()
})
function sendHistory(){
// var content = $('#content').val();
var user_id = $('[name=send_user]').val();
console.log(user_id);
// $('#content').val('')
// content.replace('\r\n',"<br/>");
if( user_id != -1 ){
var json ='{"type":3,"send_to":'+user_id+'}';
}else{
var json ='{"type":3,"send_to":"all"}';
}
console.log(json);
websocket.send(json);
}
var wsServer = 'ws://127.0.0.1:9501';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("连接成功");
showprompt();
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
// console.log( typeof evt.data);
// console.log( evt.data);
var s_data = JSON.parse( evt.data);
// console.log( s_data.type );
if( s_data.type == 'connect' ){
}else if( s_data.type == 'login' ){
if(s_data.status != 1000 ){
user_name = '';
password = '';
alert(s_data.msg);
showprompt();
}
}else if( s_data.type == 'online' ){
$('#message').find('li').last().after(
'<li>'+s_data.msg+'</li>'
);
}else if( s_data.type == 'online_list'){
console.log(s_data)
var user_list = '';
var option_list = '<option value="-1">所有人</option>';
for( var i in s_data ){
console.log(s_data[i]!='online_list')
if(s_data[i]!='online_list'){
user_list += '<li>'+s_data[i].user_name+'</li>';
option_list += '<option value="'+s_data[i].fd+'">'
+ s_data[i].user_name+'</option>'
}
}
// console.log(user_list)
// console.log(option_list)
$('#user_list').html( user_list );
$('[name=send_user]').html(option_list);
}else if( s_data.type == 'message'){
var s_mesage = s_data.msg;
var new1 =replace_em( s_mesage );
// console.log(new1);
if( s_data.isme == 1 ){
var msg = '<li style="text-align: right;">'+new1+'</li>';
}else{
var msg = '<li>'+new1+'</li>';
}
console.log(msg)
$('#message').find('li').last().after( msg );
}else if(s_data.type=='his_data'){
console.log(s_data.data)
var his_list = '<li><hr/></li>';
for( var i in s_data.data ){
if(s_data.data[i].isme==1){
his_list += '<li style="text-align: right;">'+s_data.data[i].name+':'+s_data.data[i].message+'</li>';
}else{
his_list += '<li>'+s_data.data[i].name+':'+s_data.data[i].message+'</li>';
}
}
$('#history_msg').html( his_list );
}
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
function replace_em(str){
// str = str.replace(/\</g,'<');
// str = str.replace(/\>/g,'>');
// str = str.replace(/\n/g,'<br/>');
str = str.replace(/\[em_([0-9]*)\]/g,'<img src="face/$1.gif" border="0" />');
return str;
}
</script>
php后端代码:
<?php
function async($data)
{
$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
/*$rand=range(1,100);
shuffle($rand);
$num=json_encode($rand);*/
//注册连接成功回调
$client->on("connect", function($cli)use($data){
// $cli->send("hello world\n");
$cli->send(json_encode($data));
$cli->close();
});
//注册数据接收回调
$client->on("receive", function($cli, $data){
// $cli->send($num);
echo "Received: ".$data."\n";
});
//注册连接失败回调
$client->on("error", function($cli){
echo "Connect failed\n";
});
//注册连接关闭回调
$client->on("close", function($cli){
echo "Connection close\n";
});
//发起连接
$client->connect('127.0.0.1', 3306, 0.5);
}
//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9501);
$ws->set(['task_worker_num'=>200]);
$ws->on('task',function($ws,$task_id,$form_id,$data){
echo '异步处理';
var_dump($data);
});
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
var_dump($request->fd, $request->get, $request->server);
$ws->push($request->fd, "hello, welcome\n");
});
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
$redis = new Swoole\Coroutine\Redis();
$redis->connect('127.0.0.1', 6379);
$online_str=$redis->get('online_user');
if(empty($online_str)){
$online_info=[];
}else{
$online_info=json_decode($online_str,true);
}
echo "Message: {$frame->data}\n";
$data_arr=json_decode($frame->data,true);
//登录
if($data_arr['type']==1){
if(!empty($data_arr['user_name'])&&$data_arr['password']=='123456'){
$msg=[
'type'=>'online',
'msg'=>'登陆'.$data_arr['user_name'].'登录',
'status'=>1000
];
$login_info=[
$frame->fd=>[
'user_name'=>$data_arr['user_name'],
'password'=>$data_arr['password'],
'fd'=>$frame->fd
]
];
$online_arr=$online_info+$login_info;
$redis->set('online_user',json_encode($online_arr));
$online_data=$online_arr;
$online_arr['type']='online_list';
var_dump($online_data);
foreach($online_data as $k=>$v){
$ws->push($k, json_encode($msg));
$ws->push($k, json_encode($online_arr));
}
}else{
$msg=[
'type'=>'login',
'message'=>'账号或密码不正确',
'status'=>500
];
$ws->push($frame->fd, json_encode($msg));
}
}elseif($data_arr['type']==2)
{
$swoole_mysql = new Swoole\Coroutine\MySQL();
$swoole_mysql->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => '',
'password' => '',
'database' => '',
]);
if($data_arr['send_to']=='all'){
$data=[
'type'=>'message',
'msg'=>$data_arr['user_name'].':'.$data_arr['message'],
'status'=>1000
];
foreach($online_info as $k=>$v){
if($v['fd']==$frame->fd){
$data['isme']=1;
}else{
$data['isme']=2;
}
$ws->push($k, json_encode($data));
}
$message=[
'name'=>$data_arr['user_name'],
'message'=>$data_arr['message'],
'fd'=>$frame->fd
];
//发送异步请求
// async($message);
$name=$data_arr['user_name'];
$message=$data_arr['message'];
$fd=$frame->fd;
$time=time();
$sql="insert into pub_msg VALUE (null,'$name','$message','$fd','$time')";
}else{
$data=[
'type'=>'message',
'msg'=>"<span style='color: red;'>".$data_arr['user_name'].'对你说:'.$data_arr['message']."</span>",
'status'=>1000,
'isme'=>2
];
$data2=[
'type'=>'message',
'msg'=>"<span style='color: red;'>".'你对'.$online_info[$data_arr['send_to']]['user_name'].'说:'.$data_arr['message']."</span>",
'status'=>1000,
'isme'=>1
];
$ws->push($data_arr['send_to'], json_encode($data));
$ws->push($frame->fd, json_encode($data2));
$name=$data_arr['user_name'];
$message=$data_arr['message'];
$fd=$frame->fd;
$to_fd=$data_arr['send_to'];
$time=time();
$sql="insert into pri_msg VALUE (null,'$name','$message','$fd','$to_fd','$time')";
}
$res=$swoole_mysql->query($sql);
echo $sql."\n";
if($res){
echo '记录成功';
}else{
echo '记录失败';
}
}elseif($data_arr['type']==3){
$swoole_mysql = new Swoole\Coroutine\MySQL();
$swoole_mysql->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => '',
'password' => '',
'database' => '',
]);
if($data_arr['send_to']=='all'){
$sql="select * from pub_msg order by send_time asc";
$arr=$swoole_mysql->query($sql);
foreach($arr as $k=>$v){
if($v['fd']==$frame->fd){
$arr[$k]['isme']=1;
}else{
$arr[$k]['isme']=2;
}
}
$data=[
'type'=>'his_data',
'data'=>$arr
];
}else{
$to_fd=$data_arr['send_to'];
$fd=$frame->fd;
$sqlme="select * from pri_msg where fd=$fd and to_fd=$to_fd";
$sqlit="select * from pri_msg where fd=$to_fd and to_fd=$fd";
$arr1=$swoole_mysql->query($sqlme);
$arr2=$swoole_mysql->query($sqlit);
// $arr=(array)$arr1+(array)$arr2;
$arr=array_merge((array)$arr1,(array)$arr2);
foreach($arr as $k=>$v){
if($v['fd']==$frame->fd){
$arr[$k]['isme']=1;
}else{
$arr[$k]['isme']=2;
}
}
$datetime = array();
foreach ($arr as $user) {
$datetime[] = $user['send_time'];
}
array_multisort($datetime,SORT_DESC,$arr);
$data=[
'type'=>'his_data',
'data'=>$arr
];
}
$ws->push($frame->fd, json_encode($data));
}
});
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
// echo "client-{$fd} is closed\n";
$redis = new Swoole\Coroutine\Redis();
$redis->connect('127.0.0.1', 6379);
$online_str=$redis->get('online_user');
if(empty($online_str)){
$online_info=[];
}else{
$online_info=json_decode($online_str,true);
}
$msg=[
'type'=>'online',
'msg'=>$online_info[$fd]['user_name'].'已下线',
'status'=>1000
];
unset($online_info[$fd]);
$redis->set('online_user',json_encode($online_info));
$online_data=$online_info;
$online_info['type']='online_list';
var_dump($online_data);
foreach($online_data as $k=>$v){
$ws->push($k, json_encode($msg));
$ws->push($k, json_encode($online_info));
}
});
$ws->start();
?>
本文参考swoole文档详细请看 https://wiki.swoole.com/wiki/page/397.html