php+html5基于websocket实现聊天室的方法

<?php

error_reporting(E_ALL);

ob_implicit_flush();

$sk=new Sock(‘127.0.0.1‘,8000);

$sk->run();

class Sock{

public $sockets;

public $users;

public $master;

public function __construct($address, $port){

$this->master=$this->WebSocket($address, $port);

$this->sockets=array(‘s‘=>$this->master);

}

function run(){

while(true){

$changes=$this->sockets;

socket_select($changes,$write=NULL,$except=NULL,NULL);

foreach($changes as $sock){

if($sock==$this->master){

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

//$key=uniqid();

$this->sockets[]=$client;

$this->users[]=array(

‘socket‘=>$client,

‘shou‘=>false

);

}else{

$len=socket_recv($sock,$buffer,2048,0);

$k=$this->search($sock);

if($len<7){

$name=$this->users[$k][‘ming‘];

$this->close($sock);

$this->send2($name,$k);

continue;

}

if(!$this->users[$k][‘shou‘]){

$this->woshou($k,$buffer);

}else{

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

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

}

}

}

}

}

function close($sock){

$k=array_search($sock, $this->sockets);

socket_close($sock);

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

unset($this->users[$k]);

$this->e("key:$k close");

}

function search($sock){

foreach ($this->users as $k=>$v){

if($sock==$v[‘socket‘])

return $k;

}

return false;

}

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->e(‘Server Started : ‘.date(‘Y-m-d H:i:s‘));

$this->e(‘Listening on : ‘.$address.‘ port ‘.$port);

return $server;

}

function woshou($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][‘shou‘]=true;

return true;

}

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;

}

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);

}

function ord_hex($data) {

$msg = ‘‘;

$l = strlen($data);

for ($i= 0; $i<$l; $i++) {

$msg .= dechex(ord($data{$i}));

}

return $msg;

}

function send($k,$msg){

/*$this->send1($k,$this->code($msg),‘all‘);*/

parse_str($msg,$g);

$this->e($msg);

$ar=array();

if($g[‘type‘]==‘add‘){

$this->users[$k][‘ming‘]=$g[‘ming‘];

$ar[‘add‘]=true;

$ar[‘nrong‘]=‘欢迎‘.$g[‘ming‘].‘加入!‘;

$ar[‘users‘]=$this->getusers();

$key=‘all‘;

}else if($g[‘type‘]==‘ltiao‘){

$ar[‘nrong‘]=$g[‘nr‘];

$key=$g[‘key‘];

}

$msg=json_encode($ar);

$this->e($msg);

$msg = $this->code($msg);

$this->send1($k,$msg,$key);

//socket_write($this->users[$k][‘socket‘],$msg,strlen($msg));

}

function getusers(){

$ar=array();

foreach($this->users as $k=>$v){

$ar[$k]=$v[‘ming‘];

}

return $ar;

}

function send1($k,$str,$key=‘all‘){

if($key==‘all‘){

foreach($this->users as $v){

socket_write($v[‘socket‘],$str,strlen($str));

}

}else{

if($k!=$key)

socket_write($this->users[$k][‘socket‘],$str,strlen($str));

socket_write($this->users[$key][‘socket‘],$str,strlen($str));

}

}

function send2($ming,$k){

$ar[‘remove‘]=true;

$ar[‘removekey‘]=$k;

$ar[‘nrong‘]=$ming.‘退出聊天室‘;

$str = $this->code(json_encode($ar));

$this->send1(false,$str,‘all‘);

}

function e($str){

$path=dirname(__FILE__).‘/log.txt‘;

$str=$str."\n";

error_log($str,3,$path);

echo iconv(‘utf-8‘,‘gbk//IGNORE‘,$str);

}

}

?>

时间: 2024-10-02 07:02:45

php+html5基于websocket实现聊天室的方法的相关文章

[已解决]基于WebSocket开发聊天室应用

WebSocket示例java的比较少,大部分是nodejs的,比较有名的是socket.io的chat, 借用下他的前端实现一套java的,后端基于nimbleio实现的WebSocket编写, 直接上代码: public void accept(Session session, ReadFuture future) throws Exception { if (future instanceof HttpReadFuture) { super.accept(session, future);

基于django channel 实现websocket的聊天室

websocket ? 网易聊天室? ? web微信? ? 直播? 假如你工作以后,你的老板让你来开发一个内部的微信程序,你需要怎么办?我们先来分析一下里面的技术难点 消息的实时性? 实现群聊 现在有这样一个需求,老板给到你了,关乎你是否能转正?你要怎么做? 我们先说消息的实时性,按照我们目前的想法是我需要用http协议来做,那么http协议怎么来做那? 是不是要一直去访问我们的服务器,问服务器有没有人给我发消息,有没有人给我发消息?那么大家认为我多长时间去访问一次服务比较合适那? 1分钟1次?

WebSocket 网页聊天室的实现(服务器端:.net + windows服务,前端:Html5)

websocket是HTML5中的比较有特色一块,它使得以往在客户端软件中常用的socket在web程序中也能轻松的使用,较大的提高了效率.废话不多说,直接进入题. 网页聊天室包括2个部分,后端服务器+前端页面. 1.后端服务部分:.net4.0 + windows服务.相比寄宿在iis中,寄宿在进程中的windows服务更加的稳定可靠(文章中的例子用windows控制台程序演示,后面给出完整的windows服务的代码). 2.前端部分:html5 + jQuery + bootstrap.基本

基于Tornado的websocket实现聊天室

self.render-string() 渲染成字符串 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container{ border: 2px solid #dddddd; height: 400px; overflow: auto; } &

基于 WebSocket 的聊天和大文件上传(有进度提示)完美实现

大家好,好久没有写文章了,当然不是不想写,主要是工作太忙,公司有没有网络环境,不让上网,所以写的就少了.今天是2019年的最后一天,明天就要开始新的一年,当然也希望自己有一个新的开始.在2019年的最后一天,写点东西,作为这一年的总结吧!写点啥呢?最近有时间,由于公司的需要,需要实现一个自己的.Web版本的聊天工具,当然也要能传输文件.经过两个星期的无网络.艰苦的学习,终于写出了一个最初的版本.在公司里面里面已经生成正式版本了,很多类型都进行了抽象化,支持注册,头像,私信,群聊,传输大文件,类似

Spring Boot2 系列教程 (十七) | 整合 WebSocket 实现聊天室

微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 昨天那篇介绍了 WebSocket 实现广播,也即服务器端有消息时,将消息发送给所有连接了当前 endpoint 的浏览器.但这无法解决消息由谁发送,又由谁接收的问题.所以,今天写一篇实现一对一的聊天室. 今天这一篇建立在昨天那一篇的基础之上,为便于更好理解今天这一篇,推荐先阅读:「SpringBoot 整合WebSocket 实现广播消息 」 准备工作 Spring Boot 2.1.3 RELEASE Spring S

基于java的聊天室/群发控制台程序

java聊天室 1.概述 基于tcp协议的,由一个服务器和多个客户端组成,一个客户端发送消息,其他所有客户端都能接收到消息.在服务器端设置一个线程监听客户端发来的请求(消息),并且向所有的客户端响应.每个客户端也有一个线程用来接收服务器端的请求. 2.代码如下 public class Client { public static void main(String[] args) throws IOException { //创建套接字 Socket socket = new Socket("l

nodejs+websocket制作聊天室视频教程

本套教程主要讲解了node平台的安装,node初级知识.node 服务器端程序响应http请求,通过npm安装第三方包,websocket即时通讯.聊天页面界面制作.拖动原理.拖动效果.遮罩效果.定位和浮动.滚动条滚动高度设置.用户进入与离开聊天室提示.当前在线人数的即时统计和显示.以及群聊和私聊两大聊天功能.本套教程js代码稍微有点多,对0基础的初学者可能会有一定的难度,希望通过本套教程的学习,让大家认识nodejs,感受用js写服务器端程序的乐趣. 本教程是高清完整版视频教程. 技术咨询和交

基于java网络聊天室---前言

很久之前做的一个东西,现在拿出来整理一下放在自己的博客中! 一. 设计目的 随着人互联网的发展,人和人之间的沟通方式也越来越便捷和多样化,在线聊天工具已经成为人们生活中够通不可缺少的部分,在学习完 java网络编程课程,如果能开发一款属于自己的聊天工具,和好友进行私密对话,则是一件令人兴奋的事.同时,安全可靠的TCP这两种 通信协议,是非常重要的内容,值得研究. 二. 设计内容 本聊天室程序基于C/S模式,聊天室共分为服务器端和客户端两部分,服务器端程序主要负责侦听客户端发来的消息,客户端需登陆