首页 > 代码库 > 在线客服~~

在线客服~~

SOCKET流程:
1:服务器端开启端口等待客户端建立TCP连接
2:客户端建立TCP四次握手协议TCP连接 (TCP的四次握手连接全部被封装好的代码处理)


3: 客户端发起WS协议
4:服务器判断 客户端发送消息内容即是WS协议请求
5:服务器端返回WS连接协议


6:双方建立WS长连接
7:此时客户端可以接受服务器推送过来的内容(接受WS加密内容),也可以向服务器端发送内容(服务端解码WS加密内容)。

双方关闭SOCKET

 

先看下效果~~有待加强

(1)要先链接啊,链接成功后才可以发送消息

技术分享     技术分享

(2)下面就是代码的生成了

先要编写页面,先不写链接(界面中的各个按钮)

<textarea class="log" style="width: 100%; height: 500px;">
=======websocket======
</textarea>
<input type="button" value="http://www.mamicode.com/连接" onClick="link()"> <input type="button" value="http://www.mamicode.com/断开" onClick="dis()"> <input type="text" id="text"> <input type="button" value="http://www.mamicode.com/发送" onClick="send()">

技术分享

(3)编写链接功能

<?php
class WS {
	//存储连接资源
	private $clients;
	//主线端口
	private $master;
	//客户资源
	private $user;
	private $ip;
	private $port;
	
	public function __construct($ip="127.0.0.1",$port = 3432) {
		$this->ip    = $ip;
		$this->port = $port;
		error_reporting(E_ALL);
             set_time_limit(0);
             ob_implicit_flush();
		$this->master = $this->WebSocket($this->ip,$this->port);
		$this->clients = array(‘s‘=>$this->master);
	}
	
	//建立服务器端连接
	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->log(‘开始监听: ‘.$address.‘ : ‘.$port);
            return $server;
        }
	
	
	function run() {
		while (true) {
		    $read = $this->clients;
			//var_dump($read);exit;
			@socket_select($read, $write = NULL, $except = NULL, null);
			/*if ( < 1) {
				//如果没有连接跳出
				continue;
			}*/
			
			foreach($read as $r) {
				
				if($r == $this->master) { 
				    //建立四步握手协议
				   //有客户端新进连接进来
				   //判断服务器socket是否被激活
				   //接受客户端,并将他添加到客户数组
				   $this->clients[] = $newCli = socket_accept($this->master);
				   $this->user[] = array(
				        ‘handle‘=>false,
						‘socket‘=>$newCli
				   );
				   
				   $k = $this->search($newCli);
				   echo "NUM = ".$k."\n"; //服务器端输出当前连接的 用户ID,既是数组K
				} else { 
				    //已有的连接发来的消息所有的客户数据读取
					// 读到换行符或1024字节
                   // 虽然客户端断开连接时显示错误,所以沉默错误消息
				   $buffer = ‘‘;
				   
                   $data = http://www.mamicode.com/socket_recv($r,$buffer ,2048,0);"NO---".$k;
                        $this->close($r);
                        // continue to the next client to read from
                        continue;
                    } 
					
					$k = $this->search($r);
					
					if($this->user[$k][‘handle‘] == false) { //只是进行了四步握手协议,此时浏览器发来WS协议请求
					    echo "$k=".$k."\n";
						$this->handshake($k,$buffer); //返回WS协议应答
						
					} else { //已经建立WS协议,获取通过WS发来的消息
						$str = $this->uncode($buffer);
						echo "\n".$str;
						$this->sendAll($str,$r);  //发送消息广播
					}
				}
			}
		}
	}
	
	//WebSocket 握手协议
	function handshake($k,$buffer){
		//获取KEY及生成新的KEY
		$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));
		
		//返回HTTP协议
		$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->user[$k][‘socket‘],$new_message,strlen($new_message));
		$this->user[$k][‘handle‘]=true;
		return true;
		
   }
	
	//群发消息
	function sendAll($str,$socket) {
		// 把这所有的客户在客户数组(除了第一个,这是一个监听套接字)
                foreach ($this->clients as $send_sock) {
               
                    // 如果这个资源等于 服务器或是等于它自己则跳过,
                    if ($send_sock == $this->master || $send_sock == $socket)
                        continue;
                   
                    //发送给其他用户一个信息
					$data = http://www.mamicode.com/$this->code($str);"H*", $data);
    }
	
	
    function ord_hex($data)  {  
		  $msg = ‘‘;  
		  $l = strlen($data);  
		  for ($i= 0; $i<$l; $i++) {  
			$msg .= dechex(ord($data{$i}));  
		  }  
		  return $msg;  
    }
	
	
	function log($t){//控制台输出
      
        $t=$t."\r\n";
        fwrite(STDOUT, iconv(‘utf-8‘,‘gbk//IGNORE‘,$t));
      
    }
	
	
}

$ws = new WS("127.0.0.1",8000);
$ws->run();

  

(4)写js(就是单击链接按钮和断开按钮出现的字)记得要引入jq

function link(){
    var url=‘ws://127.0.0.1:8000‘;
    socket=new WebSocket(url);
    socket.onopen=function(){
        log(‘连接成功‘);
	}
	
    socket.onmessage=function(msg) {
        log(‘获得消息:‘+msg.data);
	    console.log(msg);
    }
	
    socket.onclose=function(){log(‘断开连接‘)}
}

function dis(){
  socket.close();
  socket=null;
}

function log(var1){
  $(‘.log‘).append(var1+"\r\n");
}

function send(){
  socket.send($(‘#text‘).val());
}

这样,简单的在线客服就完成了  

在运行的时候要先运行ws,这样才能链接成功

 

在线客服~~