针对内容比较长出错,修改后的解码函数 和 加码函数 原文请看上一篇 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. 配置1000条ACE的脚本

    配置1000条ACE的脚本 测试 python 引言 在路由器或者交换机产品中,手工配置大量shell命令时,难免繁琐且效率低下,鉴于CRT中支持多种脚本语言,因此可通过脚本执行大量重复的shell配 ...

  2. JS代码判断字符串中有多少汉字【转】

    $("form").submit(function () { 2 var content = editor.getContentTxt(); 3 var sum = 0; 4 re ...

  3. 关于IE9中webdiriver使用autoit上传文件报错

    在ie9中, type="file"的元素是通过js打开的 webdirver结合autoit上传文件时,会报拒绝访问的错 sciTE编辑器中是这样写的: #include < ...

  4. 1019 JDBC链接数据库进行修删改查

    package com.liu.test01; import java.sql.Statement; import java.sql.Connection; import java.sql.Drive ...

  5. win7 、win10连接l2tpvpn

    win7:  修改vpn连接选项: win10: 参考连接: http://service.njaf.gov.cn/26970/26971/201510/t20151024_3621861.html ...

  6. html图片和文字的细节

    ul中的每一个li如果里面添加“一个图,一行字”, 这样图片会紧贴在左侧,而文字会居中,这两个元素不会紧贴着. 产生这种问题的原因我推测是:我图片设置了左浮动,但文字没有设置浮动,而一旦将文字设置为浮 ...

  7. php标签云制作——数据表的结构和查询方法

    1.数据表的结构: 创建建两张数据表,结构如下: 标签tag表: 文章mood表: 其中mood表中的tag字段,以tag表的id字段+“,”+tag表的id字段, 2.查询方法: 例如:如果需要某篇 ...

  8. Codeforces Round #192 (Div. 2)

    吐槽一下,这次的CF好简单啊. 可是我为什么这么粗心这么大意这么弱.把心沉下来,想想你到底想做什么! A 题意:O(-1) 思路:O(-1) #include <iostream> #in ...

  9. 2016HUAS暑假集训训练2 J - 今年暑假不AC

    题目链接:http://acm.hust.edu.cn/vjudge/contest/121192#problem/J 此题要求是计算能够看到最多的节目 ,贪心算法即可,首先对结束时间排序,然后在把开 ...

  10. 可以使用mysql自己带的config edit

    正常情况下,一般数据库密码可以写在用户主目录的.my.cnf 然后设置chmod 600,一般来说是比较安全的. 但是如果不想给人知道用户名和实际的密码,但是又想给人用,可以使用mysql自己带的co ...