찾다
백엔드 개발PHP 튜토리얼websocket_php 예제를 기반으로 간단한 채팅방을 구축하는 PHP 실습

이 기사의 예에서는 웹소켓을 기반으로 PHP로 간단한 채팅방을 구축하는 방법을 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 세부 내용은 다음과 같습니다.
1. 서문

회사 게임에 간단한 채팅방이 있다는 걸 알고나서 node+websocket으로 만든 줄 알았더니 PHP를 이용해 간단한 채팅방을 만들어볼까 하는 생각이 들었습니다. 그래서 다양한 정보를 수집하고, 문서를 읽고, 사례를 찾아보고, 간단한 채팅방을 직접 작성했습니다.

http 연결은 짧은 연결과 긴 연결로 구분됩니다. 짧은 연결은 일반적으로 ajax를 사용하여 구현할 수 있으며 긴 연결은 웹소켓입니다. 짧은 연결은 비교적 구현이 간단하지만 너무 많은 리소스를 소비합니다. Websocket은 효율적이지만 호환성에 몇 가지 문제가 있습니다. websocket은 html5의 리소스입니다

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웹소켓 연결과정
웹소켓 통신 다이어그램 이것은 클라이언트와 서버 간의 간단한 통신 다이어그램입니다. PHP가 주로 하는 일은 암호화 키를 수락하고 이를 반환하여 소켓 생성 및 핸드셰이크 작업을 완료하는 것입니다.

아래 사진은 웹소켓을 처리하는 서버의 세부 흐름도입니다

3.2 코드 연습

서버에서 수행되는 프로세스는 대략 다음과 같습니다.

  1. 연결을 기다리는 소켓 프로세스 정지
  2. 소켓 연결 후 소켓 배열 탐색
  3. 핸드셰이크가 없으면 핸드셰이크 작업이 수행됩니다. 핸드셰이크가 있으면 데이터를 수신하고 구문 분석하여 버퍼에 기록하여 출력합니다

다음은 샘플 코드입니다(클래스를 작성했기 때문에 코드가 기능별로 나누어져 있습니다). 텍스트 하단에는 github 주소와 제가 겪은 몇 가지 함정이 나와 있습니다.
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에서 키를 얻은 다음 암호화 알고리즘을 통해 이를 버퍼에 쓰는 것입니다(자동 확인에는 처리가 필요하지 않습니다. )

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\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($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 주소 git@github.com:rsaLive/websocket.git

①server.php를 콘솔에서 실행하는 것이 가장 좋습니다

server.php 스크립트 디렉터리로 이동합니다(먼저 php -v를 실행하여 php가 구성되어 있는지 확인할 수 있습니다. Linux 구성이 없으면 bash 창에서 경로를 구성하세요)

php -f 서버.php

오류가 있으면 메시지가 표시됩니다

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

8. 밟힌 함정에 대해서는 디버깅을 열어 오류를 확인하세요

①server.php는 중단된 프로세스에서 출력을 인쇄할 수 있습니다. 문제가 발생하면 코드에 인쇄를 추가하여 디버깅할 수 있습니다

각 판단을 표시하고 코드가 어느 섹션에서 실행되고 있는지 콘솔에서 확인할 수 있습니다

단, 코드를 수정한 후에는 매번 php server.php 스크립트를 다시 실행해야 합니다

②이 오류가 발생하면

1. 서버와 소켓 초기화 시 데이터를 보냅니다. (서버와의 첫 번째 확인 핸드셰이크 중에는 콘텐츠를 보낼 수 없습니다.)

2. 확인되었으나 클라이언트가 전송하지 않았거나 보낸 메시지가 비어 있는 경우에도 마찬가지입니다

그럼 연결된 소켓의 데이터를 확인해보세요

③ 브라우저가 지원하지 않거나 서버가 소켓을 열지 않을 수도 있습니다. 시작하기 전에 확인하는 것이 가장 좋습니다

if (window.WebSocket){
  console.log("This browser supports WebSocket!");
} else {
  console.log("This browser does not support WebSocket.");
}

위 글의 내용은 모두의 공부에 도움이 되길 바랍니다.

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP 세션에 저장된 데이터를 어떻게 수정합니까?PHP 세션에 저장된 데이터를 어떻게 수정합니까?Apr 27, 2025 am 12:23 AM

tomodifyDatainAphPessess, startSessionstession_start (), 그런 다음 $ _sessionToset, modify, orremovevariables.

PHP 세션에 배열을 저장하는 예를 제시하십시오.PHP 세션에 배열을 저장하는 예를 제시하십시오.Apr 27, 2025 am 12:20 AM

배열은 PHP 세션에 저장할 수 있습니다. 1. 세션을 시작하고 session_start ()를 사용하십시오. 2. 배열을 만들고 $ _session에 저장하십시오. 3. $ _session을 통해 배열을 검색하십시오. 4. 세션 데이터를 최적화하여 성능을 향상시킵니다.

Garbage Collection은 PHP 세션에 어떻게 효과가 있습니까?Garbage Collection은 PHP 세션에 어떻게 효과가 있습니까?Apr 27, 2025 am 12:19 AM

PHP 세션 쓰레기 수집은 만료 된 세션 데이터를 정리하기위한 확률 메커니즘을 통해 트리거됩니다. 1) 구성 파일에서 트리거 확률 및 세션 수명주기를 설정합니다. 2) CRON 작업을 사용하여 고재 응용 프로그램을 최적화 할 수 있습니다. 3) 데이터 손실을 피하기 위해 쓰레기 수집 빈도 및 성능의 균형을 맞춰야합니다.

PHP에서 세션 활동을 어떻게 추적 할 수 있습니까?PHP에서 세션 활동을 어떻게 추적 할 수 있습니까?Apr 27, 2025 am 12:10 AM

PHP의 사용자 세션 활동 추적은 세션 관리를 통해 구현됩니다. 1) Session_start ()를 사용하여 세션을 시작하십시오. 2) $ _session 배열을 통해 데이터를 저장하고 액세스하십시오. 3) 세션 _destroy ()를 호출하여 세션을 종료합니다. 세션 추적은 사용자 행동 분석, 보안 모니터링 및 성능 최적화에 사용됩니다.

데이터베이스를 사용하여 PHP 세션 데이터를 저장할 수있는 방법은 무엇입니까?데이터베이스를 사용하여 PHP 세션 데이터를 저장할 수있는 방법은 무엇입니까?Apr 27, 2025 am 12:02 AM

데이터베이스를 사용하여 PHP 세션 데이터를 저장하면 성능 및 확장 성을 향상시킬 수 있습니다. 1) 세션 데이터를 저장하기 위해 MySQL 구성 : php.ini 또는 php 코드에서 세션 프로세서를 설정하십시오. 2) 사용자 정의 세션 프로세서 구현 : 데이터베이스와 상호 작용하기 위해 열린, 닫기, 읽기, 쓰기 및 기타 기능을 정의합니다. 3) 최적화 및 모범 사례 : 인덱싱, 캐싱, 데이터 압축 및 분산 스토리지를 사용하여 성능을 향상시킵니다.

PHP 세션의 개념을 간단한 용어로 설명하십시오.PHP 세션의 개념을 간단한 용어로 설명하십시오.Apr 26, 2025 am 12:09 AM

phpsessionstrackuserdataacrossmultiplepagerequestsususingauniqueIdStoredInAcookie.here'showtomanagetheMeftically : 1) STARTASESSIONSTART_START () andSTAREDATAIN $ _SESSION.2) RegenerATERATESSESSIDIDAFTERLOGINWITHSESSION_RATERATERATES (True) TopreventSES

PHP 세션에 저장된 모든 값을 어떻게 반복합니까?PHP 세션에 저장된 모든 값을 어떻게 반복합니까?Apr 26, 2025 am 12:06 AM

PHP에서 세션 데이터를 통한 반복은 다음 단계를 통해 달성 할 수 있습니다. 1. Session_start ()를 사용하여 세션을 시작하십시오. 2. $ _session 배열의 모든 키 값 쌍을 통해 Foreach 루프를 통과합니다. 3. 복잡한 데이터 구조를 처리 할 때 is_array () 또는 is_object () 함수를 사용하고 print_r ()를 사용하여 자세한 정보를 출력하십시오. 4. Traversal을 최적화 할 때 페이징을 사용하여 한 번에 많은 양의 데이터를 처리하지 않도록 할 수 있습니다. 이를 통해 실제 프로젝트에서 PHP 세션 데이터를보다 효율적으로 관리하고 사용하는 데 도움이됩니다.

사용자 인증에 세션을 사용하는 방법을 설명하십시오.사용자 인증에 세션을 사용하는 방법을 설명하십시오.Apr 26, 2025 am 12:04 AM

이 세션은 서버 측 상태 관리 메커니즘을 통해 사용자 인증을 인식합니다. 1) 세션 생성 및 고유 ID의 세션 생성, 2) ID는 쿠키를 통해 전달됩니다. 3) ID를 통해 서버 저장 및 세션 데이터에 액세스합니다. 4) 사용자 인증 및 상태 관리가 실현되어 응용 프로그램 보안 및 사용자 경험이 향상됩니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구