websocket 封装类

后端PHP代码

<?php
class MySQLPool {

private $serv = '';
private $mysql = '';
private $teacher_openid = 'oKMfe1QTsNbzpqslEr-U1b7q8rMQ'; // 老师的微信位移标识
private $teacher_fd = ''; // 老师的文件描述符


public function __construct() {
// 创建socket套接字
$this->serv = new \swoole_websocket_server("0.0.0.0", 9502);
$this->serv->set(array(
'worker_num' => 1, //worker进程数量
'task_worker_num' => 1, //task进程数量 即为维持的MySQL连接的数量
'reactor_num'=>8,
'dispatch_mode' => 2,
'debug_mode'=> 1,
'daemonize' => 0, // 大于等于1 进程后台运行
// 'log_file' => __DIR__.'/log/webs_swoole.log',
'heartbeat_check_interval' => 60, // 表示每60秒,遍历所有连接,如果该连接在60秒内,没有向服务器发送任何数据,此连接将被强制关闭。
'heartbeat_idle_time' => 600,
));

// 绑定监听函数
$this->serv->on('WorkerStart', array($this, 'onWorkerStart'));
$this->serv->on('Open', array($this, 'onOpen'));
$this->serv->on('Connect', array($this, 'onConnect'));
$this->serv->on('Receive', array($this, 'onReceive'));
$this->serv->on('Message', array($this, 'onMessage'));
$this->serv->on('Close', array($this, 'onClose'));
// bind callback
$this->serv->on('Task', array($this, 'onTask'));
$this->serv->on('Finish', array($this, 'onFinish'));
$this->serv->start();
}


// MySQL链接数据库
public function conn_mysql(){
$mysql = new Swoole\Coroutine\MySQL();
$res = $mysql->connect([
'host' => '127.0.0.1',
'user' => 'root',
'password' => 'Bszpassword888',
'database' => 'bsz',
]);
#3
if ($res == false) {
echo("MySQL connect fail!");
return;
}
$this->mysql = $mysql;
return $mysql;
}

// 数据库插入操作
public function my_insert($tbName, $data){
$sql = "insert into ".$tbName."(".implode(',',array_keys($data)).") values(".implode(',',array_values($data)).")";
echo PHP_EOL;
echo $sql;
echo PHP_EOL;

return $this->mysql->query($sql);
}

public function onWorkerStart( $serv , $worker_id) {
echo "workerstart: ".$worker_id.PHP_EOL;

}


// 用户连接服务器响应函数
public function onOpen($serv, $data){

print_r($data->fd);
echo PHP_EOL;
// 获取老师fd
if($this->teacher_openid == $data->get['openid']){
$this->teacher_fd = $data->fd;
// echo '我是老师: ' . $this->teacher_fd;
}

扫描二维码关注公众号,回复: 5344464 查看本文章

$mysql = $this->conn_mysql();
$chat_date = date('Y-m-d', time());
$sql = "select * from bsz_chat_room where create_time >= $chat_date";
$messages = $mysql->query($sql);
// print_r($messages);
$mysql->close();

// 获取历史聊天消息记录
if(!empty($messages)){
$m_data = [];
$m_data['type'] = 'history_msg';
$m_data['fd'] = $data->fd;
$m_data['messages'] = $messages;

// $serv->task($m_data);
}

}


public function onConnect( $serv, $fd, $from_id ) {
echo "client:$fd Connect.".PHP_EOL;
}


public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
echo "receive#{$from_id}: receive $data ".PHP_EOL;
}


// 用户发送消息响应函数
public function onMessage($serv, $frame) {
echo "message: ".$frame->data.PHP_EOL;
$data = json_decode($frame->data, true);

if($data['type'] == 'heart'){ //用户发送心跳包
// 什么也不干,只是证明此用户还在聊天室, 保持长连接不中断
}else if($data['type'] == 'speak'){ // 用户发送消息
$create_time = date('Y-m-d H:i:s', time());
$msg_id = date('Ymdhis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);

// 判断消息发送者身份
if($data['msg']['openid'] == $this->teacher_openid){
$identity = '1';
$origin_identity = '1';
}else{
$identity = '2';
$origin_identity = '2';
}

$sql = "INSERT INTO `bsz`.`bsz_chat_room` (`openid`, `nickname`, `headimgurl`, `speak`, `identity`, `origin_identity`, `create_time`, `msg_id`) VALUES ('" . $data['msg']['openid']."', '". $data['msg']['nickname'] ."', '". $data['msg']['headimgurl'] ."', '". $data['msg']['speak'] ."', '$identity', '$origin_identity', '" . $create_time . "','". $msg_id ."')";

$mysql = $this->conn_mysql();
$ret = $mysql->query($sql);
echo("swoole response is ok, result=".var_export($ret, true));

// 关闭mysql连接,释放出连接数资源
$mysql->close();

$data['fd'] = $frame->fd;
$data['msg_id'] = $msg_id;
$data['teacher_openid'] = $this->teacher_openid;
$data['teacher_fd'] = $this->teacher_fd;
$data['identity'] = $identity;
$data['origin_identity'] = $origin_identity;
$serv->task($data);

}else if($data['type'] == 'replay'){ // 老师回复用户消息
$msg_id = $data['msg']['msg_id'];
$sql = "select * from `bsz_chat_room` where msg_id='$msg_id' ";
$mysql = $this->conn_mysql();
$msg = $mysql->query($sql);
// 关闭mysql连接,释放出连接数资源
$mysql->close();

$msg[0]['type'] = 'replay';
$data['msg_id'] = $msg[0]['msg_id'];
$data['msg'] = $msg[0]['msg'];
$data['openid'] = $msg[0]['openid'];
$data['nickname'] = $msg[0]['nickname'];
$data['headimgurl'] = $msg[0]['headimgurl'];

$serv->task($data);
}

}


public function onClose( $serv, $fd, $from_id ) {
echo "Client {$fd} close connection\n";
// $mysql = new Swoole\Coroutine\MySQL();
// print_r($mysql);
}


public function onTask($serv,$task_id,$from_id, $data) {
$msgArr = [];
$msgStr = '';
switch ($data['type']){
case 'login':
$msgArr['msg'] = '我来了~';
$msgArr['nickname'] = $data['msg']['nickname'];
$msgArr['headimgurl'] = $data['msg']['headimgurl'];
$msgArr['user'] = 'login';
$msgStr = json_encode($msgArr);
// $send_msg = $msgStr;
break;

case 'history_msg':
foreach ($data['messages'] as $key => $value) {
$msgArr['msg'] = $value['speak'];
$msgArr['nickname'] = $value['nickname'];
$msgArr['headimgurl'] = $value['headimgurl'];
$msgArr['user'] = 'teacher';
$msgStr = json_encode($msgArr);

$serv->push($data['fd'], $msgStr);
}

break;

case 'speak':
$msgArr['msg_id'] = $data['msg_id'];
$msgArr['msg'] = $data['msg']['speak'];
// $msgArr['openid'] = $data['msg']['openid'];
$msgArr['nickname'] = $data['msg']['nickname'];
$msgArr['headimgurl'] = $data['msg']['headimgurl'];
if($data['origin_identity'] == '1'){ // 老师发送的消息
$msgArr['user'] = 'teacher';
}else if($data['origin_identity'] == '2'){ // 粉丝发送的消息
$msgArr['user'] = 'fans';
}


// 老师发送的消息需要发送给所有人, 自己除外
if($data['teacher_openid'] == $data['teacher_openid']){
$msgStr = json_encode($msgArr);
foreach ($serv->connections as $conn){
if($conn != $data['fd']){ // 不推送消息给自己
$serv->push($conn, $msgStr);
}
}
}else{ // 其他人发送的消息,只需要转发给老师
// 添加粉丝发送消息标志
$msgStr = json_encode($msgArr);
$serv->push($data['teacher_fd'], $msgStr);
}

break;

case 'replay':
$msgArr['user'] = 'replay';
$msgArr['msg_id'] = $data['msg_id'];
$msgArr['msg'] = $data['speak'];
$msgArr['openid'] = $data['openid'];
$msgArr['nickname'] = $data['nickname'];
$msgArr['headimgurl'] = $data['headimgurl'];
$msgStr = json_encode($msgArr);
foreach ($serv->connections as $conn){
if($conn != $this->teacher_fd){ // 回复的消息不用再次推送给老师
$serv->push($conn, $msgStr);
}

}

break;

default:
break;
}

return;
}


public function onFinish($serv,$task_id, $data) {
return true;
}
}

new MySQLPool();

前端代码

<script type="text/javascript">

// 一进来就滚动到底部
// $("#container").scrollTop($("#container")[0].scrollHeight);
// $("#btnSubmit").click(function(){
// //如果没有内容就return
// var txtVal=$("#msgInput").val();
// // alert(txtVal);
// if(txtVal==''){
// return false;
// }
// //有内容继续
// $('#msgList').append('<li>'+txtVal+'</li>');
// $("#container").scrollTop($("#container")[0].scrollHeight);
// })


// 用户基本信息(头像,昵称)
var openid = "<?php echo $userinfo['openid'] ?>";
var nickname = "<?php echo $userinfo['nickname'] ?>";
var headimgurl = "<?php echo $userinfo['headimgurl'] ?>";
// https://bszedu.com/static/public/images/qq.png

// websocket连接地址
// var wsUri ="wss://127.0.0.1:9502/";
var wsUri ="wss://bszedu.com/websocket?openid=" + openid;

// JS初始化函数
function init() {
// 三次握手连接服务器
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};

// 用户断开连接
websocket.onclose = function(evt) {
onClose(evt)
};

// 客户端接收到服务器消息
websocket.onmessage = function(evt) {
onMessage(evt)
};

// socket长连接出错
websocket.onerror = function(evt) {
onError(evt)
};
}


// 获取用户需要发送的消息
function get_speak_msg(){
// var name = $("#name").val();
// var nickname = nickname;
var speak = $("#content").val();
var arr_msg = {"nickname":nickname, "speak":speak, "headimgurl":headimgurl, 'openid':openid};

return JSON.stringify(arr_msg);
}

// 打包用户消息 JSON格式
function pack_msg(type, msg){
return '{"type":"'+type+'","msg":'+msg+'}';
// var arr_msg = {"type":type, "msg":msg};
// return JSON.stringify(arr_msg);
}


// 客户端连接服务器
function onOpen(evt) {
var msgStr = '{"msg":"欢迎来到聊天室.........", "user":"welcome", "nickname":"' + nickname +'", "headimgurl":"' + headimgurl + '"}';
// var a = JSON.stringify(arr_msg);
append_speak(msgStr);
// append_speak("已经联通服务器.........");
// speak_msg = get_speak_msg();
// send_msg = pack_msg("login", speak_msg);

// doSend(send_msg);
}


function onClose(evt) {
var msgStr = '{"msg":"连接已断开!", "who":"me", "nickname":"' + nickname +'", "headimgurl":"' + headimgurl + '"}';
append_speak(msgStr);
// append_speak("俺老孙去也!");
}


function onMessage(evt) {
append_speak(evt.data);
}


function onError(evt) {
alert(evt.data);
}


function doSend(message) {
websocket.send(message);
}

function append_speak(msgStr){
var data = JSON.parse(msgStr); //由JSON字符串转换为JSON对象
// 获取当前时间
var myDate = new Date();
var msg_hour = myDate.getHours();
var msg_minute = myDate.getMinutes();
msg_hour = msg_hour<10 ? '0'+msg_hour:msg_hour;
msg_minute = msg_minute<10 ? '0'+msg_minute:msg_minute;
var chat_time = msg_hour + ':' + msg_minute;

// 老师的消息
if(data['user'] == 'teacher'){
var msg = '<li class="live-con-lis">' +
'<img src="' + data.headimgurl + '" alt="" class="live-con-img">' +
'<div class="live-con-name">' +
'<p><span class="live-con-user">' + data.nickname + '</span><span class="live-con-time">'+ chat_time +'</span></p>' +
'<span class="live-con-text">' + data.msg + '</span>' +
// '<a href="#" class="reply">回复用户></a>' +
// '<a href="javascript:;" class="reply" onclick="replay_client(this);" data-msg-id="'+ data.msg_id +'">回复用户></a>' +
'</div>' +
'</li>';

// 添加消息到聊天窗
$('#chat-msg-ul').append(msg);
// 消息滚动到底部
$(".live-con").scrollTop($(".live-con")[0].scrollHeight);

}else if(data['user'] == 'fans'){ // 粉丝的消息
var msg = '<li class="live-reviewer">' +
'<div class="live-reviewer-name">' +
'<p style="text-align: right"><span class="live-reviewer-user">'+ data.nickname+'</span><span class="live-reviewer-time">'+ chat_time +'</span></p>' +
'<div class="live-reviewer-text">' +
'<span class="live-reviewer-ask">'+ data.msg +'</span>' +
'<a href="javascript:;" class="reply" onclick="replay_client(this);" data-msg-id="'+ data.msg_id +'">回复用户></a>' +
'</div>' +
'</div>' +
'<img src="'+ data.headimgurl +'" alt="" class="live-reviewer-img">' +
'</li>';

// 添加消息到聊天窗
$('#chat-msg-ul').append(msg);
// 消息滚动到底部
$(".live-con").scrollTop($(".live-con")[0].scrollHeight);

}else if(data['user'] == 'reply'){ // 用户成功连接服务器提示
// 判断老师 和 信息发送者的 openID
if(openid != data['openid']){ // 老师回复的消息,不用再次显示在自己屏幕
var msg = '<li class="live-reviewer">' +
'<div class="live-reviewer-name">' +
'<p style="text-align: right"><span class="live-reviewer-user">'+ data.nickname+'</span><span class="live-reviewer-time">'+ chat_time +'</span></p>' +
'<div class="live-reviewer-text">' +
'<span class="live-reviewer-ask">'+ data.msg +'</span>' +
// '<a href="javascript:;" class="reply" onclick="replay_client(this);" data-msg-id="'+ data.msg_id +'">回复用户></a>' +
'</div>' +
'</div>' +
'<img src="'+ data.headimgurl +'" alt="" class="live-reviewer-img">' +
'</li>';

// 添加消息到聊天窗
$('#chat-msg-ul').append(msg);
// 消息滚动到底部
$(".live-con").scrollTop($(".live-con")[0].scrollHeight);
}

}else if(data['user'] == 'welcome'){
var msg = '<li class="live-reviewer">' +
'<div class="live-reviewer-name">' +
'<p style="text-align: right"><span class="live-reviewer-user">'+ data.nickname+'</span><span class="live-reviewer-time">'+ chat_time +'</span></p>' +
'<div class="live-reviewer-text">' +
'<span class="live-reviewer-ask">'+ data.msg +'</span>' +
'</div>' +
'</div>' +
'<img src="'+ data.headimgurl +'" alt="" class="live-reviewer-img">' +
'</li>';

// 添加消息到聊天窗
$('#chat-msg-ul').append(msg);
// 消息滚动到底部
$(".live-con").scrollTop($(".live-con")[0].scrollHeight);

}


// document.getElementById("message").value=$("#message").val()+new_msg+"\n";
// document.getElementById('message').scrollTop = document.getElementById('message').scrollHeight;
}


// 老师回复用户消息
function replay_client(obj){
var msg_id = $(obj).attr('data-msg-id');
alert(msg_id);

var arr_msg = {"msg_id":msg_id};
arr_msg = JSON.stringify(arr_msg);
send_msg = pack_msg("replay", arr_msg);
doSend(send_msg);


// alert(msg_id);
// console.log(msg_id);
}


function speak_to_all(){
// 获取当前时间
var myDate = new Date();
var msg_hour = myDate.getHours();
var msg_minute = myDate.getMinutes();
msg_hour = msg_hour<10 ? '0'+msg_hour:msg_hour;
msg_minute = msg_minute<10 ? '0'+msg_minute:msg_minute;
var chat_time = msg_hour + ':' + msg_minute;
// 获取消息输入框内容后, 清空消息输入框
// var msg_con = $("#content").val();
//如果没有内容就return
var msg_con = $("#content").val();
// alert(txtVal);
if(msg_con==''){
return false;
}
$("#content").val() == ""


// 显示自己说的话到聊天窗
if(openid == 'oKMfe1QTsNbzpqslEr-U1b7q8rMQ'){
var msg = '<li class="live-con-lis">' +
'<img src="' + headimgurl + '" alt="" class="live-con-img">' +
'<div class="live-con-name">' +
'<p><span class="live-con-user">' + nickname + '</span><span class="live-con-time">'+ chat_time +'</span></p>' +
'<span class="live-con-text">' + msg_con + '</span>' +
// '<a href="#" class="reply">回复用户></a>' +
'</div>' +
'</li>';
}else{
var msg = '<li class="live-reviewer">' +
'<div class="live-reviewer-name">' +
'<p style="text-align: right"><span class="live-reviewer-user">'+ nickname+'</span><span class="live-reviewer-time">' + chat_time + '</span></p>' +
'<div class="live-reviewer-text">' +
'<span class="live-reviewer-ask">'+ msg_con +'</span>' +
// '<a href="#" class="reply">回复用户></a>' +
'</div>' +
'</div>' +
'<img src="'+ headimgurl +'" alt="" class="live-reviewer-img">' +
'</li>';
}



// 添加消息到聊天窗
$('#chat-msg-ul').append(msg);

// 消息滚动到底部
$("#live-con").scrollTop($("#live-con")[0].scrollHeight);

// 打包消息发送到服务器
var send_msg = pack_msg("speak", get_speak_msg());
doSend(send_msg);
}

init();

// 定时发送心跳包
//循环执行,每隔1秒钟执行一次 1000
var my_heart=window.setInterval(heartbeat, 50000);
function heartbeat() {

// console.log("ready");
// 打包消息发送到服务器
var send_msg = pack_msg("heart", get_speak_msg());
doSend(send_msg);
}
//去掉定时器的方法
// window.clearInterval(my_heart);

</script>

猜你喜欢

转载自www.cnblogs.com/zhidongjian/p/10445596.html