针对内容比较长出错,修改后的解码函数 和 加码函数 原文请看上一篇 http://yixun.yxsss.com/yw3104.html

function uncode($str,$key){
$mask = array();
$data = '';
$msg = unpack('H*',$str);
$head = substr($msg[1],0,2);
if ($head == '81' && !isset($this->slen[$key])) {
$len=substr($msg[1],2,2);
$len=hexdec($len);
if(substr($msg[1],2,2)=='fe'){
$len=substr($msg[1],4,4);
$len=hexdec($len);
$msg[1]=substr($msg[1],4);
}else if(substr($msg[1],2,2)=='ff'){
$len=substr($msg[1],4,16);
$len=hexdec($len);
$msg[1]=substr($msg[1],16);
}
$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;
$n=0;
}else if($this->slen[$key] > 0){
$len=$this->slen[$key];
$mask=$this->ar[$key];
$n=$this->n[$key];
$s = 0;
} $e = strlen($msg[1])-2;
for ($i=$s; $i<= $e; $i+= 2) {
$data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2)));
$n++;
}
$dlen=strlen($data); if($len > 255 && $len > $dlen+intval($this->sjen[$key])){
$this->ar[$key]=$mask;
$this->slen[$key]=$len;
$this->sjen[$key]=$dlen+intval($this->sjen[$key]);
$this->sda[$key]=$this->sda[$key].$data;
$this->n[$key]=$n;
return false;
}else{
unset($this->ar[$key],$this->slen[$key],$this->sjen[$key],$this->n[$key]);
$data=$this->sda[$key].$data;
unset($this->sda[$key]);
return $data;
} } function code($msg){
$frame = array();
$frame[0] = '81';
$len = strlen($msg);
if($len < 126){
$frame[1] = $len<16?'0'.dechex($len):dechex($len);
}else if($len < 65025){
$s=dechex($len);
$frame[1]='7e'.str_repeat('0',4-strlen($s)).$s;
}else{
$s=dechex($len);
$frame[1]='7f'.str_repeat('0',16-strlen($s)).$s;
}
$frame[2] = $this->ord_hex($msg);
$data = implode('',$frame);
return pack("H*", $data);
}

其中主函数run 里面的接收修改为

do{
$l=socket_recv($sock,$buf,1000,0);
$len+=$l;
$buffer.=$buf;
}while($l==1000);

服务器端代码:

var fs = require('fs')
, http = require('http')
, socketio = require('socket.io'); var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
}); var ids=[];
var io=socketio.listen(server);
io.on('connection', function (socket) {
ids.push(socket.id);
socket.on('key', function (msg) {
console.log('Message Received: ', msg);
console.log('sockid:'+socket.id);
console.log(ids); io.sockets.socket(ids[0]).emit('key',msg);//向指定的用户发信息
//socket.broadcast.emit('key', msg); //公告
//socket.emit('key', msg); //发给自己
});
socket.on('disconnect',function(){
console.log('关闭'+socket.id);
});
});

客服端:

<!doctype html>
<html>
<head>
<title>sss</title>
<meta charset="utf-8">
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('key', function (data) {
document.getElementById('nr').innerHTML+=data.aa+'<br>';
}); function send(){
var v=document.getElementById('sss').value;
socket.emit('key',{'aa':v});
}
</script> </head>
<body> <div id="nr"> </div>
<input type="text" id="sss">
<button 0nClick="send();">发送</button> </body>
</html>

最近弄html5最新功能WebSocket 网上找了很多资料 都是相互抄袭 而且用不了,经过2天的折腾 终于好了,不过还有昵称是中文名的时候会自动断了的问题 估计是转码的问题。

php 的 WebSocket 13 服务器的代码

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

接上一篇 html的代码

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>socket</title>
<style type="text/css">
#cc,#cb{margin:10px auto; width:800px; border:solid 1px #CCCCCC; height:500px; font-size:14px;}
#cc p{line-height:1.8; margin:0px; padding:0px;}
#cb{height:30px; border:0px;}
#aaad{display:none;}
#aaas{display:block;}
.a{color:#008040;}
.e{color:#F33;}
.b{color:#333;}
.c{color:#999;} #autors{float:right; width:200px; height:480px; padding:10px 0px; overflow:auto; background-color:#F2F2F2;}
#content{float:left; width:580px; height:480px; padding:10px; }
#autors a{display:block; line-height:25px; color:#03C; text-decoration:none; padding:0px 10px;}
#autors .userck,#autors a:hover{background-color:#999; color:#FFF;} </style>
</head> <body>
<div id="cc">
<div id="content"></div>
<div id="autors">
<a href="javascript:;" 0nClick="ac('all',this)" class="userck">所有人</a>
</div>
</div>
<div id="cb">
<p id="aaas">
<span class="an1">设置昵称:</span>
<input type="text" maxlength="10" size="10" id="nicheg">
<input type="button" value="进入聊天室" 0nClick="aa()">
</p>
<p id="aaad">
<input type="text" maxlength="50" size="50" id="texts">
<input type="button" value="发送" 0nClick="ab()">
<input type="button" value="退出聊天室" 0nClick="az()">
</p>
</div>
<script src="http://www.yxsss.com/ui/p/a.js" type="text/javascript"></script>
<script>
var socket=null,content=A.$('content'),autors=A.$('autors'),key='all',user=[];
var an1s=document.getElementsByClassName('an1'),an2s=document.getElementsByClassName('an2');
function aa(){
var url='ws://localhost:8000';
var ming=A.$('nicheg').value.trim();
if(ming==''){
alert('昵称不能为空');
return false;
}
socket=new WebSocket(url);
socket.onopen=function(){
if(socket.readyState==1){
socket.send('type=add&ming='+ming);
}else{
content.appendChild('<p class="e">进入失败!<p>');
}
}
socket.onmessage=function(msg){
eval('var da='+msg.data);
if(da.add){
for(i in da.users){
if(typeof(user[i])=='undefined'){
var ob=A.$$('<a href="javascript:;" 0nClick="ac(\''+i+'\',this)">'+da.users[i]+'</a>');
user[i]=ob;
autors.appendChild(ob);
}
}
A.$('aaad').style.display='block';
A.$('aaas').style.display='none';
}
if(da.remove){
user[da.removekey].del();
content.appendChild(A.$$('<p class="c">'+da.nrong+'</p>'));
return ;
}
content.appendChild(A.$$('<p class="b">'+da.nrong+'</p>'));
}
socket.onclose=function(){
content.appendChild(A.$$('<p class="c">退出聊天室</p>'));
}
} function ac(k,t){
key=k;
t.parentNode.children.rcss('userck','');
t.rcss('','userck');
} function ab(){
socket.send('type=ltiao&nr='+A.$('texts').value+'&key='+key);
} function az(){
socket.close();
socket=null;
}
</script>
</body>
</html>

php +html5 websocket 聊天室的更多相关文章

  1. 使用.NET Core和Vue搭建WebSocket聊天室

    博客地址是:https://qinyuanpei.github.io.  WebSocket是HTML5标准中的一部分,从Socket这个字眼我们就可以知道,这是一种网络通信协议.WebSocket是 ...

  2. WebSocket聊天室demo

    根据Socket异步聊天室修改成WebSocket聊天室 WebSocket特别的地方是 握手和消息内容的编码.解码(添加了ServerHelper协助处理) ServerHelper: using ...

  3. Netty入门(一)之webSocket聊天室

    一:简介 Netty 是一个提供 asynchronous event-driven (异步事件驱动)的网络应用框架,是一个用以快速开发高性能.高可靠性协议的服务器和客户端. 换句话说,Netty 是 ...

  4. 用Java构建一个简单的WebSocket聊天室

    前言 首先对于一个简单的聊天室,大家应该都有一定的概念了,这里我们省略用户模块的讲解,而是单纯的先说说聊天室的几个功能:自我对话.好友交流.群聊.离线消息等. 今天我们要做的demo就能帮我们做到这一 ...

  5. websocket聊天室

    目录 websocket方法总结 群聊功能 基于websocket聊天室(版本一) websocket方法总结 # 后端 3个 class ChatConsumer(WebsocketConsumer ...

  6. 实现一个简单的WebSocket聊天室

    WebSocket 简介 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主 ...

  7. 基于springboot的websocket聊天室

    WebSocket入门 1.概述 1.1 Http #http简介 HTTP是一个应用层协议,无状态的,端口号为80.主要的版本有1.0/1.1/2.0. #http1.0/1.1/2.0 1.HTT ...

  8. 网络编程-基于Websocket聊天室(IM)系统

    目录 一.HTML5 - Websocket协议 二.聊天室(IM)系统的设计 2.1.使用者眼中的聊天系统 2.2.开发者眼中的聊天系统 2.3.IM系统的特性 2.4.心跳机制:解决网络的不确定性 ...

  9. koa2+webSocket 聊天室

    做了一个简单的的聊天室,用来看看 koa和 websocket的使用还是挺好的,已经放到gitHub. https://github.com/zhaowanhua/koa2WebSocket

随机推荐

  1. [深入浅出WP8.1(Runtime)]文本块(TextBlock)

    4.3 文本块(TextBlock) 文本块(TextBlock)控件是用于显示少量文本的轻量控件,可以通过TextBlock呈现只读的文本,你可以把TextBlock控件理解为一种纯文本的展示控件. ...

  2. 【BZOJ】1132: [POI2008]Tro

    题意 给\(n(1 \le n \le 3000)\)个点,求所有三角形的面积和. 分析 首先枚举一个点,发现把其它点按照关于这个点的极角排序后第\(i\)个点关于前面\(1\)到\(i-1\)的点组 ...

  3. 【Oracle】如何导库

    正常倒库: 步骤一:在需要导入的库里建立一个新的数据库用户 create user sms533 identified by sms533; grant dba,create session to s ...

  4. window 安装Mysql 5.6 发生系统错误 1067

    问题: #安装MySQL服务:mysqld -install MySQL5 D:\Program Files\mysql_5.6.24_winx64\bin>mysqld -install My ...

  5. python select

    server #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @author: zengchunyun " ...

  6. JSP自定义标签开发入门

    一般情况下开发jsp自定义标签需要引用以下两个包 import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; 首先我们需要大致了解开发 ...

  7. Crossing River

    Crossing River 题目链接:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=26251 题意: N个人希望去过 ...

  8. SSH集成开发框架开发步骤

    1.  环境搭建 a)添加Struts框架的支持 b)添加spring框架的支持(选中5个类库,且Copy类库到WEB-INF/lib目录下) c)在Eclipse 中,DataBase Explor ...

  9. DataTable的一些用法

    手动给DataTable添加数据 DataTable tab = new DataTable(); tab.Columns.Add("id", typeof(int));//添加列 ...

  10. 3_STL算法

    1.常用遍历算法1.1 for_each for_each(v1.begin(),v1.end(),show); void show(int &n) //回调函数的入口地址 { cout &l ...