Table of Contents
1 思路
2 服务端代码
3 页面代码
4 效果
Reading
Home Backend Development PHP Tutorial openresty+websocket+redis simple chat

openresty+websocket+redis simple chat

Jul 29, 2016 am 08:58 AM
log lt websocket

openresty 很早就支持websocket了,但是早期的版本cosocket是单工的,处理起来比较麻烦参见邮件列表讨论 websocket chat,后来的版本cosocket是双全工的,就可以按照这个讨论的方案来实现基于websocket的聊天,或者是push程序了,但是网络上没有找到一个具体一点的例子,于是自己写了个simple的例子。

1 思路

client的websocket连接到openresty之后,使用ngx.thread.spawn启动两个 轻线程,一个用来接收客户端提交的数据往redis的channel写,另一个用来订阅channel,读取redis的数据写给客户端。channel相当于一个chat room,多个client一起订阅,有人发聊天信息(pub),所有人都能得到信息(sub)。代码比较简陋,简单的思路的实现。

2 服务端代码

依赖:

  • openresty
  • redis
  • lua-resty-redis
  • lua-resty-websocket 只支持RFC 6455

nginx的配置全贴了,就是两个location,一个是页面地址,一个是websocket地址。

配置片段

<code>    location = /sredis <span>{
        content_by_lua_file conf/lua/ws_redis.lua;
    }</span>    location ~ /ws/(.*) <span>{
        alias conf/html/$1.html;
    }</span></code>
Copy after login

lua代码

<code><span>-- simple chat with redis</span><span>local</span> server = <span>require</span><span>"resty.websocket.server"</span><span>local</span> redis = <span>require</span><span>"resty.redis"</span><span>local</span> channel_name = <span>"chat"</span><span>local</span> msg_id = <span>0</span><span>--create connection</span><span>local</span> wb, err = server:new{
  timeout = <span>10000</span>,
  max_payload_len = <span>65535</span>
}

<span>--create success</span><span>if</span><span>not</span> wb <span>then</span>
  ngx.log(ngx.ERR, <span>"failed to new websocket: "</span>, err)
  <span>return</span> ngx.exit(<span>444</span>)
<span>end</span><span>local</span> push = <span><span>function</span><span>()</span></span><span>-- --create redis</span><span>local</span> red = redis:new()
    red:set_timeout(<span>5000</span>) <span>-- 1 sec</span><span>local</span> ok, err = red:connect(<span>"127.0.0.1"</span>, <span>6379</span>)
    <span>if</span><span>not</span> ok <span>then</span>
        ngx.log(ngx.ERR, <span>"failed to connect redis: "</span>, err)
        wb:send_close()
        <span>return</span><span>end</span><span>--sub</span><span>local</span> res, err = red:subscribe(channel_name)
    <span>if</span><span>not</span> res <span>then</span>
        ngx.log(ngx.ERR, <span>"failed to sub redis: "</span>, err)
        wb:send_close()
        <span>return</span><span>end</span><span>-- loop : read from redis</span><span>while</span><span>true</span><span>do</span><span>local</span> res, err = red:read_reply()
        <span>if</span> res <span>then</span><span>local</span> item = res[<span>3</span>]
            <span>local</span> bytes, err = wb:send_text(<span>tostring</span>(msg_id)..<span>" "</span>..item)
            <span>if</span><span>not</span> bytes <span>then</span><span>-- better error handling</span>
                ngx.log(ngx.ERR, <span>"failed to send text: "</span>, err)
                <span>return</span> ngx.exit(<span>444</span>)
            <span>end</span>
            msg_id = msg_id + <span>1</span><span>end</span><span>end</span><span>end</span><span>local</span> co = ngx.thread.spawn(push)

<span>--main loop</span><span>while</span><span>true</span><span>do</span><span>-- 获取数据</span><span>local</span> data, typ, err = wb:recv_frame()

    <span>-- 如果连接损坏 退出</span><span>if</span> wb.fatal <span>then</span>
        ngx.log(ngx.ERR, <span>"failed to receive frame: "</span>, err)
        <span>return</span> ngx.exit(<span>444</span>)
    <span>end</span><span>if</span><span>not</span> data <span>then</span><span>local</span> bytes, err = wb:send_ping()
        <span>if</span><span>not</span> bytes <span>then</span>
          ngx.log(ngx.ERR, <span>"failed to send ping: "</span>, err)
          <span>return</span> ngx.exit(<span>444</span>)
        <span>end</span>
        ngx.log(ngx.ERR, <span>"send ping: "</span>, data)
    <span>elseif</span> typ == <span>"close"</span><span>then</span><span>break</span><span>elseif</span> typ == <span>"ping"</span><span>then</span><span>local</span> bytes, err = wb:send_pong()
        <span>if</span><span>not</span> bytes <span>then</span>
            ngx.log(ngx.ERR, <span>"failed to send pong: "</span>, err)
            <span>return</span> ngx.exit(<span>444</span>)
        <span>end</span><span>elseif</span> typ == <span>"pong"</span><span>then</span>
        ngx.log(ngx.ERR, <span>"client ponged"</span>)
    <span>elseif</span> typ == <span>"text"</span><span>then</span><span>--send to redis</span><span>local</span> red2 = redis:new()
        red2:set_timeout(<span>1000</span>) <span>-- 1 sec</span><span>local</span> ok, err = red2:connect(<span>"127.0.0.1"</span>, <span>6379</span>)
        <span>if</span><span>not</span> ok <span>then</span>
            ngx.log(ngx.ERR, <span>"failed to connect redis: "</span>, err)
            <span>break</span><span>end</span><span>local</span> res, err = red2:publish(channel_name, data)
        <span>if</span><span>not</span> res <span>then</span>
            ngx.log(ngx.ERR, <span>"failed to publish redis: "</span>, err)
        <span>end</span><span>end</span><span>end</span>wb:send_close()
ngx.thread.wait(co)</code>
Copy after login

3 页面代码

<code><span><!DOCTYPE HTML></span><span><<span>html</span>></span><span><<span>head</span>></span><span><<span>meta</span><span>charset</span>=<span>"utf-8"</span>></span><span><<span>meta</span><span>name</span>=<span>"viewport"</span><span>content</span>=<span>"width=device-width, initial-scale=1.0, user-scalable=no"</span>></span><span><<span>script</span><span>type</span>=<span>"text/javascript"</span>></span><span><span>var</span> ws = <span>null</span>;

    <span><span>function</span><span>WebSocketConn</span><span>()</span> {</span><span>if</span> (ws != <span>null</span> && ws.readyState == <span>1</span>) {
            log(<span>"已经在线"</span>);
            <span>return</span>
        }

        <span>if</span> (<span>"WebSocket"</span><span>in</span> window) {
            <span>// Let us open a web socket</span>
            ws = <span>new</span> WebSocket(<span>"ws://localhost:8008/sredis"</span>);

            ws.onopen = <span><span>function</span><span>()</span> {</span>
                log(<span>'成功进入聊天室'</span>);
            };

            ws.onmessage = <span><span>function</span><span>(event)</span> {</span>
                log(event.data)
            };

            ws.onclose = <span><span>function</span><span>()</span> {</span><span>// websocket is closed.</span>
                log(<span>"已经和服务器断开"</span>);
            };

            ws.onerror = <span><span>function</span><span>(event)</span> {</span>
                console.log(<span>"error "</span> + event.data);
            };
        } <span>else</span> {
            <span>// The browser doesn't support WebSocket</span>
            alert(<span>"WebSocket NOT supported by your Browser!"</span>);
        }
    }

    <span><span>function</span><span>SendMsg</span><span>()</span> {</span><span>if</span> (ws != <span>null</span> && ws.readyState == <span>1</span>) {
            <span>var</span> msg = document.getElementById(<span>'msgtext'</span>).value;
            ws.send(msg);
        } <span>else</span> {
            log(<span>'请先进入聊天室'</span>);
        }
    }

    <span><span>function</span><span>WebSocketClose</span><span>()</span> {</span><span>if</span> (ws != <span>null</span> && ws.readyState == <span>1</span>) {
            ws.close();
            log(<span>"发送断开服务器请求"</span>);
        } <span>else</span> {
            log(<span>"当前没有连接服务器"</span>)
        }
    }

    <span><span>function</span><span>log</span><span>(text)</span> {</span><span>var</span> li = document.createElement(<span>'li'</span>);
        li.appendChild(document.createTextNode(text));
        document.getElementById(<span>'log'</span>).appendChild(li);
        <span>return</span><span>false</span>;
    }
    </span><span></<span>script</span>></span><span></<span>head</span>></span><span><<span>body</span>></span><span><<span>div</span><span>id</span>=<span>"sse"</span>></span><span><<span>a</span><span>href</span>=<span>"javascript:WebSocketConn()"</span>></span>进入聊天室<span></<span>a</span>></span>  
        <span><<span>a</span><span>href</span>=<span>"javascript:WebSocketClose()"</span>></span>离开聊天室<span></<span>a</span>></span><span><<span>br</span>></span><span><<span>br</span>></span><span><<span>input</span><span>id</span>=<span>"msgtext"</span><span>type</span>=<span>"text"</span>></span><span><<span>br</span>></span><span><<span>a</span><span>href</span>=<span>"javascript:SendMsg()"</span>></span>发送信息<span></<span>a</span>></span><span><<span>br</span>></span><span><<span>ol</span><span>id</span>=<span>"log"</span>></span><span></<span>ol</span>></span><span></<span>div</span>></span><span></<span>body</span>></span><span></<span>html</span>></span></code>
Copy after login

4 效果

用iphone试了试,不好使,可能是websocket版本实现的问题。pc端测试可以正常使用。

openresty+websocket+redis  simple chat

Reading

  • 邮件列表讨论 websocket chat
  • Aapo Websocket with openresty
').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });

以上就介绍了openresty+websocket+redis simple chat,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to achieve real-time communication using PHP and WebSocket How to achieve real-time communication using PHP and WebSocket Dec 17, 2023 pm 10:24 PM

With the continuous development of Internet technology, real-time communication has become an indispensable part of daily life. Efficient, low-latency real-time communication can be achieved using WebSockets technology, and PHP, as one of the most widely used development languages ​​in the Internet field, also provides corresponding WebSocket support. This article will introduce how to use PHP and WebSocket to achieve real-time communication, and provide specific code examples. 1. What is WebSocket? WebSocket is a single

How to implement an online speech recognition system using WebSocket and JavaScript How to implement an online speech recognition system using WebSocket and JavaScript Dec 17, 2023 pm 02:54 PM

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

The combination of Java and WebSocket: how to achieve real-time video streaming The combination of Java and WebSocket: how to achieve real-time video streaming Dec 17, 2023 pm 05:50 PM

With the continuous development of Internet technology, real-time video streaming has become an important application in the Internet field. To achieve real-time video streaming, the key technologies include WebSocket and Java. This article will introduce how to use WebSocket and Java to implement real-time video streaming playback, and provide relevant code examples. 1. What is WebSocket? WebSocket is a protocol for full-duplex communication on a single TCP connection. It is used on the Web

Combination of golang WebSocket and JSON: realizing data transmission and parsing Combination of golang WebSocket and JSON: realizing data transmission and parsing Dec 17, 2023 pm 03:06 PM

The combination of golangWebSocket and JSON: realizing data transmission and parsing In modern Web development, real-time data transmission is becoming more and more important. WebSocket is a protocol used to achieve two-way communication. Unlike the traditional HTTP request-response model, WebSocket allows the server to actively push data to the client. JSON (JavaScriptObjectNotation) is a lightweight format for data exchange that is concise and easy to read.

PHP and WebSocket: Best practices for real-time data transfer PHP and WebSocket: Best practices for real-time data transfer Dec 18, 2023 pm 02:10 PM

PHP and WebSocket: Best Practice Methods for Real-Time Data Transfer Introduction: In web application development, real-time data transfer is a very important technical requirement. The traditional HTTP protocol is a request-response model protocol and cannot effectively achieve real-time data transmission. In order to meet the needs of real-time data transmission, the WebSocket protocol came into being. WebSocket is a full-duplex communication protocol that provides a way to communicate full-duplex over a single TCP connection. Compared to H

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems WebSocket and JavaScript: key technologies for implementing real-time monitoring systems Dec 17, 2023 pm 05:30 PM

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

How to use Java and WebSocket to implement real-time stock quotation push How to use Java and WebSocket to implement real-time stock quotation push Dec 17, 2023 pm 09:15 PM

How to use Java and WebSocket to implement real-time stock quotation push Introduction: With the rapid development of the Internet, real-time stock quotation push has become one of the focuses of investors. The traditional stock market push method has problems such as high delay and slow refresh speed. For investors, the inability to obtain the latest stock market information in a timely manner may lead to errors in investment decisions. Real-time stock quotation push based on Java and WebSocket can effectively solve this problem, allowing investors to obtain the latest stock price information as soon as possible.

How does Java Websocket implement online whiteboard function? How does Java Websocket implement online whiteboard function? Dec 17, 2023 pm 10:58 PM

How does JavaWebsocket implement online whiteboard function? In the modern Internet era, people are paying more and more attention to the experience of real-time collaboration and interaction. Online whiteboard is a function implemented based on Websocket. It enables multiple users to collaborate in real-time to edit the same drawing board and complete operations such as drawing and annotation. It provides a convenient solution for online education, remote meetings, team collaboration and other scenarios. 1. Technical background WebSocket is a new protocol provided by HTML5. It implements

See all articles