> 백엔드 개발 > PHP 튜토리얼 > WebSocket 사용 참고 사항

WebSocket 사용 참고 사항

WBOY
풀어 주다: 2016-07-29 09:05:51
원래의
924명이 탐색했습니다.

1. 소개

웹페이지에서 여러 메시지를 빠르게 보내고 받으려면 WebSocket이 이러한 요구를 해결하는 데 매우 적합합니다. 이번에는 WebSocket을 사용하여 채팅 웹 애플리케이션을 구축했습니다. 주로 클라이언트 구현과 관련됩니다. 서버는 PHP로 구현된 WebSocket 서버를 사용합니다. 이 기사에서는 자세히 소개하지 않습니다.
주요 JavaScript 코드는 다음과 같습니다.

  • new WebSocket이 websocket 객체를 생성합니다.
  • socket.onopen은 연결 설정 후 트리거됩니다.
  • socket.onerror는 연결이 설정된 후 트리거됩니다. 오류 발생
  • socket.onmessage는 데이터 수신 시 트리거
  • socket.onclose는 연결이 닫힐 때 트리거
  • socket.send()는 데이터 전송

2. 결과

최종 구현은 서버에 메시지를 보내는 것이며, 서버는 동일한 메시지를 반환합니다. 사진을 클릭하시면 온라인 디스플레이 버전 링크를 다운로드 받으실 수 있습니다

WebSocket 사용 참고 사항

온라인 버전은 여기

코드

JavaScript

<code><span>var</span> socket;
<span>var</span> submit = document.getElementById(<span>'submit'</span>);<span>//首先输入聊天者名字,提交后可开始聊天</span><span>var</span> button = document.getElementById(<span>'send'</span>);<span>//发送按钮</span>
button.addEventListener(<span>'click'</span>, sendMsg);
submit.addEventListener(<span>'click'</span>, startChat);
<span><span>function</span><span>startChat</span><span>()</span>{</span>
    document.getElementById(<span>'modal'</span>).style.visibility = <span>"collapse"</span>;
    document.getElementById(<span>'modalBody'</span>).style.visibility = <span>"collapse"</span>;
    connect();<span>//连接服务器</span>
}
<span>//发送消息</span><span><span>function</span><span>sendMsg</span><span>()</span>{</span><span>var</span> txetArea = document.getElementById(<span>'sendText'</span>);
    <span>var</span> content = txetArea.value;
    <span>var</span> client = document.getElementById(<span>'name'</span>).value;
    showMsg(content,<span>0</span>);
    txetArea.value = <span>""</span>;
    msg = {
        name: client,
        message: content
    }
    socket.send(<span>JSON</span>.stringify(msg)); <span>//发送数据</span>
}
<span>//显示消息</span><span><span>function</span><span>showMsg</span><span>(content,type)</span>{</span><span>var</span> mainDiv = document.getElementById(<span>'main'</span>);
    <span>var</span> div = document.createElement(<span>'div'</span>);
    mainDiv.appendChild(div);
    <span>var</span> lineDiv = mainDiv.lastChild;
    lineDiv.className = <span>'line'</span>;
    lineDiv.innerHTML = (<span><span>function</span><span>()</span>{</span><span>if</span> (type == <span>0</span>){
            <span>return</span><span>"<div class='\"selfContent\"'></div>"</span>;
        }
        <span>else</span> {
            <span>return</span><span>"<div class='\"content\"'></div>"</span>;
        }
    })();
    <span>var</span> contentDiv = lineDiv.lastChild;
    contentDiv.innerHTML = content;
    mainDiv.scrollTop = mainDiv.scrollHeight - mainDiv.clientHeight;
}
<span>//建立连接</span><span><span>function</span><span>connect</span><span>()</span>{</span><span>var</span> http_request;
    <span>if</span> (window.XMLHttpRequest){ 
         http_request = <span>new</span> XMLHttpRequest();
         <span>if</span> (http_request.overrideMimeType){
            http_request.overrideMimeType(<span>'text/xml'</span>);
         }
    } <span>else</span><span>if</span> (window.ActiveXObject) { 
        <span>try</span> {
            http_request = <span>new</span> ActiveXObject(<span>"Msxml2.XMLHTTP"</span>);
        } <span>catch</span> (e){
            <span>try</span> {
                http_request = <span>new</span> ActiveXObject(<span>"Microsoft.XMLHTTP"</span>);
            } <span>catch</span> (e){}
        }
    }
    http_request.open(<span>'GET'</span>, <span>"http://localhost/websocket/server.php"</span>, <span>true</span>);
    http_request.send();
    socket = <span>new</span> WebSocket(<span>"ws://localhost:9000/websocket/server.php"</span>);
    socket.onopen = open; <span>//绑定成功打开后触发的函数</span>
    socket.onmessage = recMessage; <span>//绑定接受到数据后的处理函数</span>
    socket.onerror = error; <span>//绑定处理错误的函数</span>
    socket.onclose = close; <span>//绑定连接关闭后的处理函数</span>
}
<span>//连接成功</span><span><span>function</span><span>open</span><span>()</span>{</span><span>var</span> i = document.getElementsByTagName(<span>'i'</span>);
    i[<span>0</span>].innerHTML = <span>'连接成功!'</span>;
    button.disabled = <span>''</span>;
}
<span>//出错</span><span><span>function</span><span>error</span><span>()</span>{</span><span>var</span> i = document.getElementsByTagName(<span>'i'</span>);
    i[<span>0</span>].style.color = <span>"#FF0000"</span>;
    i[<span>0</span>].innerHTML = <span>'连接失败'</span>;
    button.disabled = <span>'disabled'</span>;
}
<span>//接受到数据</span><span><span>function</span><span>recMessage</span><span>(e)</span>{</span><span>var</span> data = <span>JSON</span>.parse(e.data);
    showMsg(data.message, <span>1</span>);
}
<span>//连接关闭</span><span><span>function</span><span>close</span><span>()</span>{</span>
    button.disabled = <span>'disabled'</span>;
    <span>if</span> (confirm(<span>'连接已关闭,是否需要再次连接?'</span>)){
        connect();
    }
}</code>
로그인 후 복사

클래스

<code><span><span><?php </span><span>namespace</span><span>MyLab</span>;

<span><span>class</span><span>WebSocket</span>{</span><span>private</span><span>$host</span>;
    <span>private</span><span>$port</span>;
    <span><span>function</span><span>__construct</span><span>(<span>$port</span>, <span>$host</span>)</span>
    {</span><span>$this</span>->host = <span>$host</span>;
        <span>$this</span>->port = <span>$port</span>;
    }
    <span>//启动服务</span><span><span>function</span><span>StartServer</span><span>()</span>{</span><span>$socket</span> = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);<span>//创建socket</span>
        socket_set_option(<span>$socket</span>, SOL_SOCKET, SO_REUSEADDR, <span>1</span>);
        socket_bind(<span>$socket</span>, <span>0</span>, <span>$this</span>->port);
        socket_listen(<span>$socket</span>);<span>//开启监听</span><span>$sockets</span> = <span>array</span>(<span>$socket</span>);
        <span>$write</span> = <span>NULL</span>;
        <span>$except</span> = <span>NULL</span>;
        <span>while</span> (<span>true</span>)
        {
            <span>$clients</span> = <span>$sockets</span>;
            <span>$num</span> = socket_select(<span>$clients</span>, <span>$write</span>, <span>$except</span>, <span>0</span>);
            <span>if</span> (<span>$num</span> === <span>false</span>){
                <span>echo</span><span>"socket_select failed!"</span>;
                <span>break</span>;
            }
            <span>if</span> (in_array(<span>$socket</span>, <span>$clients</span>))
            {
                <span>$socket_new</span> = socket_accept(<span>$socket</span>); <span>//接受连接</span><span>$sockets</span>[] = <span>$socket_new</span>; <span>//保存连接</span><span>$header</span> =  socket_read(<span>$socket_new</span>, <span>1024</span>);
                <span>$status</span> = <span>$this</span>->handshaking(<span>$header</span>, <span>$socket_new</span>, <span>$this</span>->host, <span>$this</span>->port);
                <span>$response</span> = <span>$this</span>->code(json_encode(<span>array</span>(<span>'message'</span>=><span>'欢迎来到Chat with yourself'</span>)));
                <span>$status</span> = <span>$this</span>->sendMessage(<span>$response</span>, <span>$socket_new</span>);<span>//首次连接上之后回应</span><span>$found_socket</span> = array_search(<span>$socket</span>, <span>$clients</span>);
                <span>unset</span>(<span>$clients</span>[<span>$found_socket</span>]);
            }
            <span>foreach</span> (<span>$clients</span><span>as</span><span>$client</span>) <span>//遍历连接,处理接受到的消息</span>
            {
                <span>while</span> (socket_recv(<span>$client</span>, <span>$buf</span>, <span>1024</span>, <span>0</span>) >= <span>1</span>)
                {
                    <span>$received_text</span> = <span>$this</span>->decode(<span>$buf</span>);
                    <span>$decode_text</span> = json_decode(<span>$received_text</span>);
                    <span>$user_name</span> = <span>$decode_text</span>->name;
                    <span>$user_message</span> = <span>$decode_text</span>->message;
                    <span>$response_text</span> = <span>$this</span>->code(json_encode(<span>array</span>(<span>'type'</span> => <span>'usermsg'</span>, <span>'name'</span> => <span>$user_name</span>, <span>'message'</span> => <span>$user_message</span>)));
                    <span>$this</span>->sendMessage(<span>$response_text</span>, <span>$client</span>);
                    <span>break</span><span>2</span>;
                }
            }
        }
    }
    <span>//握手验证</span><span><span>function</span><span>handshaking</span><span>(<span>$receved_header</span>,<span>$client_conn</span>, <span>$host</span>, <span>$port</span>)</span>
    {</span><span>$headers</span> = <span>array</span>();
        <span>$lines</span> = preg_split(<span>"/\r\n/"</span>, <span>$receved_header</span>);
        <span>foreach</span>(<span>$lines</span><span>as</span><span>$line</span>)
        {
            <span>$line</span> = chop(<span>$line</span>);
            <span>if</span>(preg_match(<span>'/\A(\S+): (.*)\z/'</span>, <span>$line</span>, <span>$matches</span>))
            {
                <span>$headers</span>[<span>$matches</span>[<span>1</span>]] = <span>$matches</span>[<span>2</span>];
            }
        }

        <span>$secKey</span> = <span>$headers</span>[<span>'Sec-WebSocket-Key'</span>];
        <span>$secAccept</span> = base64_encode(pack(<span>'H*'</span>, sha1(<span>$secKey</span> . <span>'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'</span>)));
        <span>$upgrade</span>  = <span>"HTTP/1.1 101 Web Socket Protocol Handshake\r\n"</span> .
        <span>"Upgrade: websocket\r\n"</span> .
        <span>"Connection: Upgrade\r\n"</span> .
        <span>"WebSocket-Origin: $host\r\n"</span> .
        <span>"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n"</span>.
        <span>"Sec-WebSocket-Accept:$secAccept\r\n\r\n"</span>;
        socket_write(<span>$client_conn</span>,<span>$upgrade</span>,strlen(<span>$upgrade</span>));
        <span>return</span><span>$upgrade</span>;
    }
    <span>//解码</span><span><span>function</span><span>decode</span><span>(<span>$str</span>)</span>
    {</span><span>$length</span> = ord(<span>$str</span>[<span>1</span>]) & <span>127</span>;
        <span>if</span> (<span>$length</span> == <span>126</span>)
        {
            <span>$masks</span> = substr(<span>$str</span>, <span>4</span>, <span>4</span>);
            <span>$data</span> = substr(<span>$str</span>, <span>8</span>);
        }
        <span>elseif</span> (<span>$length</span> == <span>127</span>) {
            <span>$masks</span> = substr(<span>$str</span>, <span>10</span>, <span>4</span>);
            <span>$data</span> = substr(<span>$str</span>, <span>14</span>);
        }
        <span>else</span> {
            <span>$masks</span> = substr(<span>$str</span>, <span>2</span>, <span>4</span>);
            <span>$data</span> = substr(<span>$str</span>, <span>6</span>);
        }
        <span>$str</span> = <span>''</span>;
        <span>for</span> (<span>$i</span> = <span>0</span>; <span>$i</span> $data</span>); ++<span>$i</span>)
        {
            <span>$str</span> .= <span>$data</span>[<span>$i</span>] ^ <span>$masks</span>[<span>$i</span> % <span>4</span>];
        }
        <span>return</span><span>$str</span>;
    }
    <span>//发送消息</span><span><span>function</span><span>sendMessage</span><span>(<span>$msg</span>, <span>$cilent</span>)</span>
    {</span><span>try</span>{

            <span>return</span> socket_write(<span>$cilent</span>, <span>$msg</span>, strlen(<span>$msg</span>));
        }
        <span>catch</span> (\<span>Exception</span><span>$e</span>){
            <span>return</span><span>$e</span>;
        }
    }
    <span>//编码</span><span><span>function</span><span>code</span><span>(<span>$str</span>)</span>
    {</span><span>$b1</span> = <span>0x80</span> | (<span>0x1</span> & <span>0x0f</span>);
        <span>$length</span> = strlen(<span>$str</span>);
        <span>if</span> (<span>$length</span> 125</span>)
            <span>$header</span> = pack(<span>'CC'</span>, <span>$b1</span>, <span>$length</span>);
        <span>elseif</span> (<span>$length</span> ><span>125</span> && <span>$length</span> 65536)
            <span>$header</span> = pack(<span>'CCn'</span>, <span>$b1</span>, <span>126</span>, <span>$length</span>);
        <span>elseif</span> (<span>$length</span> >= <span>65536</span>)
            <span>$header</span> = pack(<span>'CCNN'</span>, <span>$b1</span>, <span>127</span>, <span>$length</span>);
        <span>else</span> {
            <span>return</span><span>false</span>;
        }
        <span>return</span><span>$header</span>.<span>$str</span>;
    }

}</code>
로그인 후 복사
').addClass('pre-numbering').hide();로 캡슐화된 PHP 서버 코드 $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });

이상으로 관련 내용을 포함한 WebSocket 사용법을 소개하였습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되었으면 좋겠습니다.

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿