在socket出现之前已经有ajax定时请求、长轮询等方案,但都不能满足某些特定情况下的需求,基于此,socket就应运而生了。

总结下常用的socket函数

服务端: socket_create 创建socket设置基本参数

socket_bind 绑定ip和端口号

socket_listen 监听

socket_accept 客户端的连接

socket_read 读取客户端的数据

socket_write 给单独客户端发送数据

socket_close 关闭连接

客户端:socket_create 创建socket设置基本参数

socket_connect 连接socket

socket_write 给服务端发送数据

socket_read 读取服务端数据

socket_close 关闭连接

服务端代码socket.php(名字自己定义):

class WS {

var $master;

var $sockets = array();

var $debug = false;//true为调试模式,输出log日志

var $handshake = array();

function __construct($address, $port){

$this->master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed");

socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed");

socket_bind($this->master, $address, $port) or die("socket_bind() failed");

socket_listen($this->master,20) or die("socket_listen() failed");

$this->sockets[] = $this->master;

$this->say("Server Started : ".date('Y-m-d H:i:s'));

$this->say("Listening on : ".$address." port ".$port);

$this->say("Master socket : ".$this->master."\n");

while(true){

$socketArr = $this->sockets;

$write = NULL;

$except = NULL;

socket_select($socketArr, $write, $except, NULL); //自动选择来消息的socket 如果是握手 自动选择主机

foreach ($socketArr as $socket){

if ($socket == $this->master){ //主机

$client = socket_accept($this->master);

if ($client < 0){

$this->log("socket_accept() failed");

continue;

} else{

$this->connect($client);

}

} else {

$bytes = @socket_recv($socket,$buffer,2048,0);

if ($bytes == 0){

$this->disConnect($socket);

}

else{

$key = array_search($socket, $this->sockets);

if (empty($this->handshake) || !isset($this->handshake[$key]) || !$this->handshake[$key]){

$this->doHandShake($socket, $buffer, $key);

}

else{

$buffer = $this->decode($buffer);

echo $buffer.PHP_EOL;

$key = array_search($socket, $this->sockets);

$arr = $this->sockets;

array_shift($arr);

foreach ($arr as $s){

$this->send($s, $buffer);

}

}

}

}

}

}

}

function send($client, $msg){

// $msg = $this->frame($msg);

$msg = $this->frame('恭喜你,成功了');

socket_write($client, $msg, strlen($msg));

}

function connect($socket){

array_push($this->sockets, $socket);

$this->say("\n" . $socket . " CONNECTED!");

$this->say(date("Y-n-d H:i:s"));

}

function disConnect($socket){

$index = array_search($socket, $this->sockets);

socket_close($socket);

$this->say($socket . " DISCONNECTED!");

if ($index >= 0){

echo 'unset index is:'.PHP_EOL;

unset($this->sockets[$index]);

}

}

function doHandShake($socket, $buffer, $handKey){

$this->log("\nRequesting handshake...");

$this->log($buffer);

list($resource, $host, $origin, $key) = $this->getHeaders($buffer);

$this->log("Handshaking...");

$upgrade = "HTTP/1.1 101 Switching Protocol\r\n" .

"Upgrade: websocket\r\n" .

"Connection: Upgrade\r\n" .

"Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n\r\n"; //必须以两个回车结尾

$this->log($upgrade);

$sent = socket_write($socket, $upgrade, strlen($upgrade));

$this->handshake[$handKey]=true;

$this->log("Done handshaking...");

return true;

}

function getHeaders($req){

$r = $h = $o = $key = null;

if (preg_match("/GET (.*) HTTP/" ,$req,$match)) { $r = $match[1]; }

if (preg_match("/Host: (.*)\r\n/" ,$req,$match)) { $h = $match[1]; }

if (preg_match("/Origin: (.*)\r\n/" ,$req,$match)) { $o = $match[1]; }

if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)) { $key = $match[1]; }

return array($r, $h, $o, $key);

}

function calcKey($key){

//基于websocket version 13

$accept = base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));

return $accept;

}

function decode($buffer) {

$len = $masks = $data = $decoded = null;

$len = ord($buffer[1]) & 127;

if ($len === 126) {

$masks = substr($buffer, 4, 4);

$data = substr($buffer, 8);

}

else if ($len === 127) {

$masks = substr($buffer, 10, 4);

$data = substr($buffer, 14);

}

else {

$masks = substr($buffer, 2, 4);

$data = substr($buffer, 6);

}

for ($index = 0; $index < strlen($data); $index++) {

$decoded .= $data[$index] ^ $masks[$index % 4];

}

return $decoded;

}

function frame($s){

$a = str_split($s, 125);

if (count($a) == 1){

return "\x81" . chr(strlen($a[0])) . $a[0];

}

$ns = "";

foreach ($a as $o){

$ns .= "\x81" . chr(strlen($o)) . $o;

}

return $ns;

}

function say($msg = ""){

echo $msg . "\n";

}

function log($msg = ""){

if ($this->debug){

echo $msg . "\n";

}

}

}

new WS('localhost', 4000);

客户端代码index.html(H5):

demo

var ws = new WebSocket("ws://localhost:4000");

ws.onopen = function(){

console.log("握手成功");

}

ws.onmessage = function(e){

console.log("message:" + e.data);

}

ws.onerror = function(){

console.log("error");

}

$("#send").click(function(){

content = $("#content").val();

console.log(content);

ws.send(content);

})

然后到socket.php所在的目录执行php socket.php 开启socket(直接使用php命令要添加环境变量),linux下执行nohup php demo.php &可以在后台执行,浏览器打开多个index.html,就能建立通讯了。

php怎么实现即时聊天,php实现socket即时通讯示例相关推荐

  1. 基于Android的聊天软件,Socket即时通信,实现用户在线聊天

    基于Android的聊天软件,Socket即时通信,单聊,聊天室,可自行扩展功能,完善细节. [实例功能] 1.运行程序,登录界面, 注册账号功能 2.进入主界面,有通讯录, 个人信息. 3.点击好友 ...

  2. Node.js + Web Socket 打造即时聊天程序嗨聊(上)

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...

  3. [前端] Node.js + Web Socket 打造即时聊天程序嗨聊

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...

  4. Node.js + Web Socket 打造即时聊天程序嗨聊(1)

    2019独角兽企业重金招聘Python工程师标准>>> 本文将使用Node.js加web socket协议打造一个网页即时聊天程序,取名为HiChat,中文翻过来就是'嗨聊',听中文 ...

  5. Node.js + Socket.io 实现一对一即时聊天

    实现一对一即时聊天应用,重要的一点就是消息能够实时的传递,一种方案就是熟知的使用 Websocket 协议,本文中我们使用 Node.js 中的一个框架 http://Socket.io 来实现. 效 ...

  6. 【Android】基于Socket的即时聊天(群聊)

    近来感觉秋招无望,学习Socket的时候,便做了个基于Socket的群聊工具: 先看看最终效果吧 项目GitHub通道(详细代码请自行copy) 如何利用Socket通信 socket又称为" ...

  7. 基于Socket的TCP协议Linux聊天系统(即时聊天、传送文件)

    基于Socket的TCP协议Linux聊天系统(即时聊天.传送文件)有源码!!!! 4.1 需求分析 4.1.1 系统目的 4.1.2 系统结构图 4.1.3 系统功能 4.1.4 系统数据流图 4. ...

  8. Android 深入实现基于socket套接字的即时聊天

    实现功能 1.历史消息存储 2.未读消息存储 题记 程序猿小白第一次写博客,有不足和改进的地方希望大家多多指教!有关用socket实现即时聊天简易功能的文章csdn上一抓一大把,博主最近在做的一款ap ...

  9. Android即时通讯--仿QQ即时聊天:(一)初识Socket

    1.即时通讯简介 即时通讯(Instant Messaging,简称IM)是一个终端服务,允许两人或者多人通过网络即时传递文字讯息.档案.语音等.简单的概括就是发送消息时,只要对方在线,就能立即接收到 ...

最新文章

  1. 油管网红AI老师人设崩了:搞培训货不对板,谈退钱一律拉黑
  2. 防止网站内容被人小偷和采集的ASP代码
  3. Python 操作 MySQL 的正确姿势
  4. Kettle7 java 远程执行Trans/Job
  5. ch=cin.get()和cin.get(ch)返回值问题
  6. Apache Cassandra和Java入门(第二部分)
  7. android 运行jquery,Android端JQueryMobile使用教程(一)
  8. stl min函数_std :: min()函数以及C ++ STL中的示例
  9. 页面回填当前日期与时间
  10. 每天一个linux命令(60):scp命令
  11. shiro执行多个过滤器_Shiro 实战(四) - 过滤器机制
  12. 转:在windows中将tree命令加入git-bash中
  13. delphi2007 打开项目时,突然报错,提示microsoft.net borland 报错
  14. creator小功能----浅谈cc.Director与 资源加载策略
  15. 学习笔记(4):《微电子器件》陈星弼(第四版)第2章 PN结
  16. ucwords和ucfirst用法举例!!
  17. spring跨重定向传递数据
  18. 我对IT项目经理工作的理解
  19. sql 修改时间正价 2天_“熬夜3天,修改17遍,我终于写出了1篇稿费2万的稿子”...
  20. 个税革新,你每年能省多少钱~

热门文章

  1. C++判断网络是否连接
  2. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础
  3. Objective-c 静态变量的定义
  4. 1352. 虫洞【难度: 中 / 枚举 判环】
  5. Telnet连接详细步骤
  6. centos7下使用kubeadm安装k8s
  7. uni-app小程序v-show内容始终不显示
  8. Spring boot自动注册DispatcherServlet
  9. 再见 Win10!下一代操作系统来了。。
  10. MySQL 面试必备:又一神器“锁”,不会的在面试都挂了