websocket 聊天机器人
websocket.class.php:
<?php
header("Content-type: text/html; charset=utf-8");
/*
创建类websocket($config);
$config结构:
$config=array( 'address'=>'192.168.0.200',//绑定地址 'port'=>'8000',//绑定端口 'event'=>'WSevent',//回调函数的函数名 'log'=>true,//命令行显示记录
); 回调函数返回数据格式
function WSevent($type,$event) $type字符串 事件类型有以下三种
in 客户端进入
out 客户端断开
msg 客户端消息到达
均为小写 $event 数组
$event['k']内置用户列表的userid;
$event['sign']客户标示
$event['msg']收到的消息 $type='msg'时才有该信息 方法:
run()运行
search(标示)遍历取得该标示的id
close(标示)断开连接
write(标示,信息)推送信息
idwrite(id,信息)推送信息 属性:
$users 客户列表
结构:
$users=array(
[用户id]=>array('socket'=>[标示],'hand'=[是否握手-布尔值]),
[用户id]=>arr.....
)
*/ class websocket
{public $log; public $event; public $signets; public $users; public $master;public function __construct($config) { if (substr(php_sapi_name(), 0, 3) !== 'cli') { die("请通过命令行模式运行!"); } error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $this->event = $config['event']; $this->log = $config['log']; $this->master=$this->WebSocket($config['address'], $config['port']); $this->sockets=array('s'=>$this->master); }public function WebSocket($address, $port) {$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1); socket_bind($server, $address, $port); socket_listen($server); $this->log('开始监听: ' . $address . ' : ' . $port); return $server; }public function run() {while(true) { $changes=$this->sockets; @socket_select($changes, $write=NULL, $except=NULL,NULL); foreach ($changes as $sign) {if($sign==$this->master) {$client=socket_accept($this->master); $this->sockets[] = $client; $user = array( 'socket' => $client, 'hand' => false, ); $this->users[] = $user; $k = $this->search($client); $eventreturn = array('k' => $k,'sign' => $sign); $this->eventoutput('in', $eventreturn); } else {$len=socket_recv($sign, $buffer, 2048, 0); $k = $this->search($sign); $user = $this->users[$k]; if ($len < 7) { $this->close($sign); $eventreturn = array('k' => $k,'sign' => $sign); $this->eventoutput('out',$eventreturn); continue; } if (!$this->users[$k]['hand']) {//没有握手进行握手 $this->handshake($k,$buffer); } else { $buffer = $this->uncode($buffer); $eventreturn = array('k' => $k,'sign' => $sign, 'msg' => $buffer); $this->eventoutput('msg', $eventreturn); } } } } }public function search($sign) {//通过标示遍历获取idforeach ($this->users as $k => $v) {if($sign == $v['socket']) {return $k;}} return false; } public function close($sign) {//通过标示断开连接 $k=array_search($sign, $this->sockets); socket_close($sign); unset($this->sockets[$k]); unset($this->users[$k]); } public function handshake($k,$buffer) { $buf = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18); $key = trim(substr($buf,0,strpos($buf,"\r\n"))); $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true)); $new_message = "HTTP/1.1 101 Switching Protocols\r\n"; $new_message .= "Upgrade: websocket\r\n"; $new_message .= "Sec-WebSocket-Version: 13\r\n"; $new_message .= "Connection: Upgrade\r\n"; $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n"; socket_write($this->users[$k]['socket'],$new_message,strlen($new_message)); $this->users[$k]['hand']=true; return true; }public function uncode($str) { $mask = array(); $data = ''; $msg = unpack('H*',$str); $head = substr($msg[1],0,2); if (hexdec($head{1}) === 8) {$data = false; } else if (hexdec($head{1}) === 1) { $mask[] = hexdec(substr($msg[1],4,2)); $mask[] = hexdec(substr($msg[1],6,2)); $mask[] = hexdec(substr($msg[1],8,2)); $mask[] = hexdec(substr($msg[1],10,2)); $s = 12; $e = strlen($msg[1])-2; $n = 0; for ($i=$s; $i<= $e; $i+= 2) { $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2))); $n++; } } return $data; }public function code($msg) {$msg = preg_replace(array('/\r$/','/\n$/','/\r\n$/',), '', $msg); $frame = array(); $frame[0] = '81'; $len = strlen($msg); $frame[1] = $len<16?'0'.dechex($len):dechex($len); $frame[2] = $this->ord_hex($msg); $data = implode('',$frame); return pack("H*", $data); }public function ord_hex($data) { $msg = ''; $l = strlen($data); for($i= 0; $i<$l; $i++) { $msg .= dechex(ord($data{$i})); } return $msg; } public function idwrite($id,$t) {//通过id推送信息 if(!$this->users[$id]['socket']){return false;}//没有这个标示 $t=$this->code($t); return socket_write($this->users[$id]['socket'],$t,strlen($t)); }public function write($k,$t) {//通过标示推送信息 $t=$this->code($t); return socket_write($k,$t,strlen($t)); } public function eventoutput($type,$event) {//事件回调 call_user_func($this->event,$type,$event); }public function log($t) {//控制台输出 if($this->log) { $t=$t."\r\n"; fwrite(STDOUT, iconv('utf-8','gbk//IGNORE',$t)); } }
}
server.php:
<?php
header("Content-type: text/html; charset=utf-8");
include 'websocket.class.php'; $config = array( 'address'=>'10.16.77.216', 'port'=>'8008', 'event'=>'WSevent',//回调函数的函数名 'log'=>true,
);
$websocket = new websocket($config);
$websocket->run();
function WSevent($type, $event){ global $websocket; if ('in' == $type) { $websocket->log('客户进入id: ' . $event['k']); } else if ('out' == $type) { $websocket->log('客户退出id: ' . $event['k']); } else if ('msg' == $type) { $websocket->log('客户:' . $event['k'] . '消息: ' . $event['msg']); roboot($event['sign'], $event['msg']); }
} function roboot($sign,$t) { global $websocket; switch ($t) { case 'hello': $show = 'hello,GIt @ OSC'; break; case 'name':$show = 'Robot'; break; case 'time': $show = '当前时间:' . date('Y-m-d H:i:s'); break; case '再见': $show='( ^_^ )/~~拜拜'; $websocket->write($sign, 'Robot:' . $show); $websocket->close($sign); return; break; case '天王盖地虎': $array = array('小鸡炖蘑菇', '宝塔震河妖', '粒粒皆辛苦'); $show = $array[rand(0,2)]; break; default: $show='( ⊙o⊙?)不懂,你可以尝试说:hello,name,time,再见,天王盖地虎.'; } $websocket->write($sign, 'Robot:' . $show);
}
index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>websocket_TEST</title>
</head>
<body>
<textarea class="log" style="width: 100%; height: 500px;">
=======websocket======
</textarea>
<input type="button" value="连接" onClick="link()">
<input type="button" value="断开" onClick="dis()">
<input type="text" id="text">
<input type="button" value="发送" onClick="send()">
<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
<script>
function link(){ var url='ws://10.16.77.216:8008'; socket=new WebSocket(url); socket.onopen=function(){log('连接成功')} socket.onmessage=function(msg){log('获得消息:'+msg.data);console.log(msg);} socket.onclose=function(){log('断开连接')}
}
function dis(){ socket.close(); socket=null;
}
function log(var1){ $('.log').append(var1+"\r\n");
}
function send(){ socket.send($('#text').val());
}
function send2(){ var json = JSON.stringify({'type':'php','msg':$('#text').val()}) socket.send(json);
}
</script>
</body>
</html>
运行界面:
websocket 聊天机器人相关推荐
- 基于python以及AIUI WebSocket,WeChatPYAPI实现的微信聊天机器人
基于python以及AIUI WebSocket,WeChatPYAPI实现的微信聊天机器人 做此文的目的首先是学习Markdown的用法哈哈哈哈,其实也是记录自己学习的一个过程. 以后我也会将自己在 ...
- 如何用 Slack 和 Kubernetes 构建一个聊天机器人?| 附代码
作者 | Alexander Kainz 译者 | 天道酬勤,责编 | Carol 出品 | AI科技大本营(ID:rgznai100) ChatOps可以让你使用基于聊天的接口来管理DevOps任务 ...
- python制作聊天机器人原理_用 Python 来做一个聊天机器人吧!(一)
在我的一个回答里,我提到了用 Python 搭建聊天机器人.从今天开始,我就带着大家从0开始搭建一个聊天机器人. (顺便说一句,我喜欢把链接像上面这样加在文字里,如果找不到文中所说的资源,可以看看周围 ...
- 使用socket.io搭建一个实时聊天机器人
一.安装socket.io npm i socket.io --save 二.使用 第一种:服务端使用原生node // 创建http服务器 const http = require('http') ...
- 机器人编程python代码_自己动手开发智能聊天机器人完全指南(附python完整源码)...
一.前言 人工智能时代,开发一款自己的智能问答机器人,一方面提升自己的AI能力,另一方面作为转型AI的实战练习.在此把学习过程记录下来,算是自己的笔记. 二.正文 2.1 下载pyaiml 下载pya ...
- 如何运用Python建立你的第一个Slack聊天机器人?
聊天机器人(Bot) 是一种像 Slack 一样的实用的互动聊天服务方式.如果你之前从来没有建立过聊天机器人,那么这篇文章提供了一个简单的入门指南,告诉你如何用 Python 结合 Slack API ...
- 我开发了一个温柔的智能客服聊天机器人ChatBot,并回答为什么不是ChatGPT(附思路和代码)
前言 若问2023年科技领域什么最火,那当然是ChatGPT了,这么智能的对话机器人,给人带来无限的想象,围绕着ChatpGPT的各种热点和创意层出不穷.作为一个多年从事编程开发的程序员,我对于这么大 ...
- html 简单机器人对话页面,简单的js聊天机器人框架BotUI
Botui是一款简单的js聊天机器人框架.Botui基于Vue.js,通过简单配置,就可以制作出一个功能简单的聊天机器人,非常神奇. 使用方法 在页面中引入botui.min.css和botui-th ...
- 聊天机器人革命即将到来 开发者入局需谨慎
10月12日消息,据VentureBeat报道,毫无疑问,聊天机器人是"现在的大事(Now Big Thing)",谁都想从中分一杯羹.可是如果你犯了错误,那可能会伤及自己的企业, ...
最新文章
- php 删除xls文件,使用PHPExcel将xls文件转换为xlsx时出错
- 去年亏11亿的寒武纪拟科创板募资28亿:三年总营收5.68亿,99%客户来自国内,曾从华为海思挖来CTO...
- elasticsearch in查询_Python Elasticsearch DSL 查询、过滤、聚合操作实例
- java实现bean实体与map集合相互转换
- Ext.Net 1.2.0_Ext.Net.TreePanel 勾选“纠结”发送给服务器端的方法
- [Oracle]Sqlplus 中使用 new_value
- 开放源代码_您对开放源代码感兴趣了多少年?
- Log4J 1.x 配置详解
- Python设置Tkinter窗口屏幕居中
- base64原理及其编解码的python实现
- 服务器日志默认存放位置,系统日志和IIS日志存放路径
- java和是10的10次方的素数,10的11次方之内相邻两素数的最大差值
- php 阿里云 批量 单个 发送短信 (拿来即用)
- blender布尔运算差值看不出效果/blender布尔差值无效
- Ubuntu系统的内核架构介绍
- Self-supervised
- Tensorflow2.0学习-Keras Tuner 妙用 (六)
- 绘制图形可以使用什么python函数_如何对绘制PDF图形的Python函数进行单元测试?...
- TMF和Frameworx
- Android开发--Udp方式的数据传输