php与websocket
① php如何实现websocket
php有可用的websocket库,不需要php-fpm。
目前比较成熟的有swoole(swoole.com),和workman(workman.net)
swoole是c写的php扩展, 效率比nodejs还要高,workman是纯php实现,两者都号称可以实现并发百万TCP连接。
给你个例子:
这个要通过cmd运行的具体带的参数有点忘记了
<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
//创建一个socket连接设置参数绑定监听并且返回
$master=WebSocket("localhost",12345);
//标示是否已经进行过握手了
$is_shaked=false;
//是否已经关闭
$is_closed=true;
//将socket变为一个可用的socket
while(true){
//如果是关闭状态并且是没有握手的话则创建一个可用的socket(貌似第二个条件可以去除)
if($is_closed&&!$is_shaked){
if(($sock=socket_accept($master))<0){
echo"socket_accept()failed:reason:".socket_strerror($sock)." ";
}
//将关闭状态修改为false
$is_closed=false;
}
//开始进行数据处理
process($sock);
}
//处理请求的函数
functionprocess($socket){
//先从获取到全局变量
global$is_closed,$is_shaked;
//从socket中获取数据
$buffer=socket_read($socket,2048);
//如果buffer返回值为false并且已经握手的话则断开连接
if(!$buffer&&$is_shaked){
disconnect($socket);
}else{
//如果没有握手的话则握手并且修改握手状态
if($is_shaked==false){
$return_str=dohandshake($buffer);
$is_shaked=true;
}else{
//如果已经握手的话则送入deal函数中进行相应处理
$data_str=decode($buffer);//解析出来的从前端送来的内容
console($data_str);
$return_str=encode(deal($socket,$data_str));
//$return_str=encode($data_str);
}
//将应该返回的字符串写入socket返回
socket_write($socket,$return_str,strlen($return_str));
}
}
functiondeal($socket,$msgObj){
$obj=json_decode($msgObj);
foreach($objas$key=>$value){
if($key=='close'){
disconnect($socket);
console('closesuccess');
return'closesuccess';
}elseif($key=='msg'){
console($value." ");
return$value;
}
}
}
//获取头部信息
functiongetheaders($req){
$r=$h=$o=null;
if(preg_match("/GET(.*)HTTP/",$req,$match)){$r=$match[1];}
if(preg_match("/Host:(.*) /",$req,$match)){$h=$match[1];}
if(preg_match("/Origin:(.*) /",$req,$match)){$o=$match[1];}
if(preg_match("/Sec-WebSocket-Key:(.*) /",$req,$match)){$key=$match[1];}
if(preg_match("/ (.*?)$/",$req,$match)){$data=$match[1];}
returnarray($r,$h,$o,$key,$data);
}
functionWebSocket($address,$port){
$master=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)ordie("socket_create()failed");
socket_set_option($master,SOL_SOCKET,SO_REUSEADDR,1)ordie("socket_option()failed");
socket_bind($master,$address,$port)ordie("socket_bind()failed");
socket_listen($master,20)ordie("socket_listen()failed");
echo"ServerStarted:".date('Y-m-dH:i:s')." ";
echo"Mastersocket:".$master." ";
echo"Listeningon:".$address."port".$port." ";
return$master;
}
functiondohandshake($buffer){
list($resource,$host,$origin,$key,$data)=getheaders($buffer);
echo"resourceis$resource ";
echo"originis$origin ";
echo"hostis$host ";
echo"keyis$key ";
$response_key=base64_encode(sha1($key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11',true));
$return_str="HTTP/1.1101SwitchingProtocols ".
"Upgrade:websocket ".
"Connection:Upgrade ".
"Sec-WebSocket-Accept:$response_key ";
return$return_str;
}
functionconsole($msg){
$msg=transToGBK($msg);
echo"$msg ";
return$msg;
}
functiondecode($msg=""){
$mask=array();
$data="";
$msg=unpack("H*",$msg);
$head=substr($msg[1],0,2);
if(hexdec($head{1})===8){
$data=false;
}elseif(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;
}
functionencode($msg=""){
$frame=array();
$frame[0]="81";
$msg.='isok';
$len=strlen($msg);
$frame[1]=$len<16?"0".dechex($len):dechex($len);
$frame[2]=ord_hex($msg);
$data=implode("",$frame);
returnpack("H*",$data);
}
functiontransToGBK($s){//UTF8->GBK
//echo$s;
returniconv("UTF-8","GBK",$s);
return$s;
}
functionord_hex($data){
$msg="";
$l=strlen($data);
for($i=0;$i<$l;$i++){
//ord是返回字符串第一个字符的ascii值
//dechex把十进制转换为十六进制
$msg.=dechex(ord($data{$i}));
}
return$msg;
}
functiondisconnect($socket){
global$is_shaked,$is_closed;
$is_shaked=false;
$is_closed=true;
socket_close($socket);
}
?>
② 如何用php实现websocket
html5自带有websocket,这是客户端的。
php可以使用swoole框架来实现websocket。
或则自己解析websocket协议,使用php自带的socket。
友情提示:在以上情况的时候,php是运行在cli模式下的,这样才能让程序常驻内存。
③ php实现websocket实时消息推送
一、socket协议的简介
WebSocket是什么,有什么优点
WebSocket是一个持久化的协议,这是相对于http非持久化来说的。应用层协议
举个简单的例子,http1.0的生命周期是以request作为界定的,也就是一个request,一个response,对于http来说,本次client与server的会话到此结束;而在http1.1中,稍微有所改进,即添加了keep-alive,也就是在一个http连接中可以进行多个request请求和多个response接受操作。然而在实时通信中,并没有多大的作用,http只能由client发起请求,server才能返回信息,即server不能主动向client推送信息,无法满足实时通信的要求。而WebSocket可以进行持久化连接,即client只需进行一次握手,成功后即可持续进行数据通信,值得关注的是WebSocket实现client与server之间全双工通信,即server端有数据更新时可以主动推送给client端。
二、介绍client与server之间的socket连接原理
1、下面是一个演示client和server之间建立WebSocket连接时握手部分
2、client与server建立socket时握手的会话内容,即request与response
a、client建立WebSocket时向服务器端请求的信息
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket //告诉服务器现在发送的是WebSocket协议
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== //是一个Base64 encode的值,这个是浏览器随机生成的,用于验证服务器端返回数据是否是WebSocket助理
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
b、服务器获取到client请求的信息后,根据WebSocket协议对数据进行处理并返回,其中要对Sec-WebSocket-Key进行加密等操作
HTTP/1.1 101 Switching Protocols
Upgrade: websocket //依然是固定的,告诉客户端即将升级的是Websocket协议,而不是mozillasocket,lurnarsocket或者shitsocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= //这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key,也就是client要求建立WebSocket验证的凭证
Sec-WebSocket-Protocol: chat
3、socket建立连接原理图:
三、PHP中建立websocket的过程讲解
SocketService.php:
web.html:
④ php 怎么使用websocket推送消息
首先:WebSocket 不是一门技术,而是一种全新的协议。它应用 TCP 的 Socket(套接字),为网络应用定义了一个新的重要的能力:客户端和服务器端的双全工传输和双向通信。是继 Java applets、 XMLHttpRequest、 Adobe Flash,、ActiveXObject、 各类 Comet 技术之后,服务器推送客户端消息的新趋势。
其次:与http的关系
在网络分层上,websocket 与 http 协议都是应用层的协议,它们都是基于 tcp 传输层的,但是 websocket 在建立连接时,是借用 http 的 101 switch protocol 来达到协议转换(Upgrade)的,从 HTTP 协议切换成 WebSocket 通信协议,这个动作协议中称“握手”;
握手成功后,websocket 就使用自己的协议规定的方式进行通讯,跟 http 就没有关系了。
用户在socket检测用户上下线的是时候 可以http请求到自己的api层下面我贴一下我的代码
这个地方明确表明了监听端口,websocket跟api在同一个服务器上面,所以用了0.0.0.0,所以你在http服务端如果想发消息给客户端,只需要发送到这个端口上面,socket自动会监听到发送给客户端。
⑤ php websocket连接报错怎么解决
php websocket连接报错一般是握手连接失败导致。
php 用websocket,从连接、建立、绑定、监听等,这些都需要手动去操作。配置错误会导致无法连接。
下梁枣面是client和server端建立websocket连接示意图:
解析:
1、PHP 中处理 WEBSOCKET
WebSocket 连接是由客户端主动发起的,所以一切要从客户端出发。第一步是要解析拿到客户端发过来的 Sec-WebSocket-Key 字符串。
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: .com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
2、提取 SEC-WEBSOCKET-KEY 信息
function getKey($req) {
$key = null;
if (preg_match("/Sec-WebSocket-Key: (.*)/r/n/", $req, $match)) {
$key = $match[1];
}
return $key;
}
3、加密 SEC-WEBSOCKET-KEY
function encry($req){
$key = $this->getKey($req);
$mask = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
return base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
}
以上闭辩任何一个环节出错都会导致失败。轿渣缺
⑥ 如何用PHP实现基于websocket的实时通讯
哈哈,过了这么几年了,websocket已经相当稳定和成熟了。
各大浏览器都对websocket有了很好的支持,目前微信小程序也支持websocket协议了,那些说websocket不稳定的可以暂时歇一歇了。
如果是自己开发websocket服务,可以用swoole等来实现,不过要做好还是需要花很多时间和精力的。
你可以试试【GoEasy】提供的websocket推送服务,目前算是比较流行的一款websocket推送框架,稳定性还不错,对多种前后端都有很好的支持的。
⑦ 如何使用GoEasy实现PHP与Websocket实时通信
如何使用GoEasy实现PHP与Websocket实时通信
实现步骤如下:
1. 获取GoEasy appkey.
在goeasy官网上注册一个账号,并新建一个app. APP创建好后系统会为该app自动生成两个key, 一个既可以用来接收又可以用来推送 (supper key),另一个只可以用来接收(subscriber key).
2. 客户端订阅一个channel.
a. 在客户端引入goeasy.js, js地址:
需要注意的是,不能将goeasy.js下载到本地,因为goeasy会根据不同浏览器来提供不同的js. 官网上也有相隐握应说明。
b. 订阅代码
var goEasy = new GoEasy({appkey: 'subscriber key'});//这里我用的是subscriber key,因为在我的客户端我不需要推送任何消息,所以没有必要使用supper key
goEasy. subscribe({
channel: 'csdnNotification',
onMessage: function(message){
alert('Meessage received:'+message.content);//接收到推送的消息
}
});
复制代码
3. 前台推送及后台推送
3.1. 前台往相同channel上推送
在引入了好携孝goeasy.js的页面,直接调用goEasy. publish('csdnNotification', '您的好友222已上线'); 用法与订阅类似。
3.2. 后台往相同channel上推送. 用GoEasy提供的restful API实现
API url:
方式: Post
参数列表:
channel: 'csdnNotification' //与订阅的友稿channel必须一致,否则客户端将收不到消息。因此我们也可以根据channel来控制哪些客户端可以接收。
appkey: 'supper key' //这里必须使用supper key
content: 'blabla…..' //要推送的内容
⑧ 如何用php实现websocket
websocket需要php监听一个固定或尺的端口,而不是请求的时候再去执行 一般的主机服务无法实现此功能 如果你有服务器的设置权限,可以在服务器上用php命令开启端口,再用nginx做一空宏个Websocket代理 大多数虚拟主机服务商是不支持自己配置服衫亏高务器的