php 웹 소켓 기반 간이 채 팅 방 구축 실천

8474 단어 phpsocket채 팅 방
본 고 는 php 가 웹 소켓 을 바탕 으로 간이 채 팅 방 을 구축 하 는 실천 을 실례 로 서술 하 였 다.모두 에 게 참고 하도록 공유 하 다.구체 적 으로 다음 과 같다.
1.머리말
회사 게임 에 간단 한 채 팅 방 이 있 습 니 다.알 고 보 니 node+websocket 이 만 들 었 다 는 것 을 알 게 되 었 습 니 다.phop 을 생각해 서 간단 한 채 팅 방 을 만 들 겠 습 니 다.그래서 각종 자 료 를 수집 하여 문 서 를 보고 실례 를 찾 아 자신 도 간단 한 채 팅 방 을 썼 다.
http 연결 은 짧 은 연결 과 긴 연결 로 나 뉜 다.짧 은 연결 은 일반적으로 ajax 로 이 루어 질 수 있 으 며,긴 연결 은 websocket 입 니 다.짧 은 연결 은 실현 하기는 비교적 간단 하지만 자원 을 너무 소모 한다.웹 소켓 은 효율 적 이지 만 호환성 에 문제 가 있 습 니 다.웹 소켓 은 html 5 의 자원 입 니 다.
2.전단
전단 에서 웹 소켓 을 실현 하 는 것 은 매우 간단 하고 직접적 이다.

//  websocket

var ws = new WebSocket("ws://127.0.0.1:8000");

//    websoc   

ws.onopen = function(){}

//            

ws.onmessage = function(e){}

//       
ws.onerror = function(){}

//        

ws.send();
3.백 스테이지
웹 소켓 의 난점 은 주로 배경 에 있 습 니 다.
3.1 websocket 연결 과정
웹 socket 통신 도해 이것 은 간단 한 클 라 이언 트 와 서버 의 통신 도해 입 니 다.php 는 주로 암호 화 키 를 받 아들 이 는 것 입 니 다.  소켓 생 성과 악수 작업 을 마 친 상태 로 되 돌아 갑 니 다.

아래 그림 은 상세 한 서버 에서 웹 소켓 을 처리 하 는 프로 세 스 그림 입 니 다.

3.2 코드 실천
서버 에서 하 는 절 차 는 대체로 다음 과 같다.
연결 을 기다 리 는 socket 소켓 프로 세 스 를 걸 어 라4
  • socket 연결 이 있 으 면 소켓 배열 을 옮 겨 다 닙 니 다
  • 악 수 를 하지 않 고 악 수 를 했다 면 데이터 분석 을 받 고 버퍼 에 기록 하여 출력 한다.
  • 다음은 예제 코드 입 니 다.
     1.우선 소켓 만 들 기
     
    
    //     
        public function createSocket($address,$port)
        {
          //       
          $socket= socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
          //       
          socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
          //  IP     
          socket_bind($socket,$address,$port);
          //     
          socket_listen($socket);
          return $socket;
        }
    
    2.소켓 을 배열 에 넣 기
    
    public function __construct($address,$port)
        {
          //     
          $this->soc=$this->createSocket($address,$port);
          $this->socs=array($this->soc);
    
        }
    
    
    3.프로 세 스 를 걸 고 소켓 배열 을 옮 겨 다 니 며 주요 작업 은 이 안에서 이 루어 집 니 다.
    
    public function run(){
          //    
          while(true){
            $arr=$this->socs;
            $write=$except=NULL;
            //               
            socket_select($arr,$write,$except, NULL);
            //       
            foreach($arr as $k=>$v){
              //                       
              if($this->soc == $v){
                $client=socket_accept($this->soc);
                if($client <0){
                  echo "socket_accept() failed";
                }else{
                  // array_push($this->socs,$client);
                  // unset($this[]);
                  //                
                  $this->socs[]=$client;
                }
              }else{
                //     socket          socket       
                $byte=socket_recv($v, $buff,20480, 0);
                //        0
                if($byte<7)
                  continue;
                //                ,           
                if(!$this->hand[(int)$client]){
                  //      
                  $this->hands($client,$buff,$v);
                }else{
                  //      
                  $mess=$this->decodeData($buff);
                    //    
                  $this->send($mess,$v);
                }
              }
            }
          }
        }
    
    4.악수 절 차 를 진행 하 는 것 은 웹 소켓 내용 을 받 아들 여 Sec-webSocket-Key:에서 key 를 가 져 오고 암호 화 알고리즘 을 통 해 버퍼 클 라 이언 트 에 기록 하여 검증 하 는 것 입 니 다(자동 검증 은 우리 가 처리 할 필요 가 없습니다)
    
    public function hands($client,$buff,$v)
        {
          //  websocket  key      (           Sec-WebSocket-Key:   key)
          $buf = substr($buff,strpos($buff,'Sec-WebSocket-Key:')+18);
          //        
          $key = trim(substr($buf,0,strpos($buf,"\r
    "))); // $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true)); $new_message = "HTTP/1.1 101 Switching Protocols\r
    "; $new_message .= "Upgrade: websocket\r
    "; $new_message .= "Sec-WebSocket-Version: 13\r
    "; $new_message .= "Connection: Upgrade\r
    "; $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r
    \r
    "; // socket_write($v,$new_message,strlen($new_message)); // socket_write(socket,$upgrade.chr(0), strlen($upgrade.chr(0))); // $this->hand[(int)$client]=true; }
    5.클 라 이언 트 의 데 이 터 를 분석 합 니 다.
    
    //    
        public function decodeData($buff)
        {
          //$buff      
          $mask = array(); 
          $data = ''; 
          $msg = unpack('H*',$buff); // unpack           
          $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)); 
              //                     state connecting
            $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++; 
            }
            //        
              //      125      
              $block=str_split($data,125);
              $mess=array(
                'mess'=>$block[0],
                );
            return $mess;          
          }
    
    6.소켓 을 버퍼 에 기록 합 니 다.
    
    //    
        public function send($mess,$v)
        {
          //                    
          foreach ($this->socs as $keys => $values) {
            //           id      
              $mess['name']="Tourist's socket:{$v}";
              $str=json_encode($mess);
              $writes ="\x81".chr(strlen($str)).$str;
              // ob_flush();
              // flush();
              // sleep(3);
              if($this->hand[(int)$values])
                socket_write($values,$writes,strlen($writes));
            }
        }
    
    7.운행 방법
    github 주소
    ① 콘 솔 에서 server.php 를 실행 하 는 것 이 좋다.
    server.phop 스 크 립 트 디 렉 터 리 로 이동(phop-v 에서 phop 설정 이 있 는 지 확인 할 수 있 습 니 다.Linux 설정 이 없 으 면 bash windows 설정 에서 path)
    php -f server.php

    오류 가 있 으 면 힌트 를 드릴 게 요.

    ② 서버 를 통 해 html 파일 에 접근


    8.밟 은 구 덩이 는 디 버 깅 작업 을 열 어 오 류 를 쉽게 볼 수 있 습 니 다.
    ① server.phop 이 걸 려 있 는 프로 세 스에 서 출력 을 출력 할 수 있 습 니 다.문제 가 발생 하면 코드 에 인쇄 를 추가 하여 디 버 깅 할 수 있 습 니 다.
    각 판단 에 표 시 를 해서 콘 솔 에서 코드 가 어느 구간 에서 실행 되 는 지 볼 수 있 습 니 다.
    하지만 코드 를 수정 할 때마다 스 크 립 트 php server.php 를 다시 실행 해 야 합 니 다.
    ② 이런 오류 가 발생 하면

    1.서버 와 초기 소켓 을 연결 할 때 데 이 터 를 보 냅 니 다(서버 와 악 수 를 처음 검증 할 때 내용 을 보 낼 수 없습니다)
    2.검 증 했 지만 클 라 이언 트 가 보 내지 않 거나 보 낸 메시지 가 비어 있 으 면 이런 상황 이 발생 할 수 있 습 니 다.
    그래서 연 결 된 소켓 의 데 이 터 를 확인 해 야 합 니 다.
     
    ③ 브 라 우 저가 지원 하지 않 거나 서버 에서 socket 을 열지 않 았 을 수도 있 습 니 다.시작 하기 전에 확인 하 는 것 이 좋 습 니 다.
    
    if (window.WebSocket){
      console.log("This browser supports WebSocket!");
    } else {
      console.log("This browser does not support WebSocket.");
    }
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기