Best practices for timely communication

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Describe

Lhttp is a websocket server-based framework that provides an HTTP-like protocol to help developers develop long-connected applications.

The use of lhttp can greatly reduce the workload of server-side development, enabling very good modularity and decoupling of business functions.

You can customize any function you want.

Project Address

Characteristics

    • Simple to use, powerful

    • High performance, using GNATSD Message Queuing Publish 10,000 messages is time consuming 0.04s (Single-core cpu,1g memory).

    • Supports clustering, scale-out, and increased server access for higher service capabilities

    • Very container for customization and expansion

    • Can work well with HTTP services, such as sending messages using HTTP, forwarding messages to upstream HTTP servers, and so on. So even if you don't go the language can also develop some applications.

Chat Room Demo

Front-End SDK

Protocol stack:

+--------------------+|       lhttp        |+--------------------+|     websocket      |+--------------------+|        TCP         |+--------------------+

System architecture

        +---------------------------------------+        |    message center cluster (gnatsd)    |        +---------------------------------------+ ........|.................|...............|..................| +-------------+   +-------------+   +-------------+        | | |lhttp server |   |lhttp server |   |lhttp server |   ...  |  lhttp 服务集群| +-------------+   +-------------+   +-------------+        |  .....|..........._____|  |___.............|  |_________......      |          |            |            |            |       <----使用websocket链接 +--------+  +--------+   +--------+   +--------+   +--------+    | client |  | client |   | client |   | client |   | client |    +--------+  +--------+   +--------+   +--------+   +--------+  

Quick Start

go get github.com/nats-io/natsgo get github.com/fanux/lhttp

Start GNATSD First:

Open another terminal, execute the client program, enter the command code:

cd bin./lhttpClient

Use the Docker quick experience

$ docker build -t lhttp:latest .$ docker run -p 9090:9090 -p 8081:8081 lhttp:latest

Open Browser, Access: http://localhost:9090 .

Open up to two windows and you can talk.

The WebSocket port is 8081 and can use its own WebSocket client to connectws://localhost:8081

You can also download images from Dockerhub:

$ docker run -p 9090:9090 -p 8081:8081 fanux/lhttp:latest

Protocol Introduction

LHTTP/1.0 Command\r\n                --------起始行,协议名和版本,Command:非常重要,标识这条消息的命令码是什么,服务端也是根据命令码注册对应的处理器的。Header1:value\r\n                    --------首部Header2:value\r\n\r\nbody                                 --------消息体

Case:

LHTTP/1.0 chat\r\n                  命令码叫`chat`content-type:json\r\n               消息体使用json编码publish:channel_jack\r\n            服务端请把这条消息publish给jack (jack订阅了channel_jack)\r\n{    to:jack,    from:mike,    message:hello jack,    time:1990-1210 5:30:48}

With a tutorial, you need only three steps

Define your processor and need aggregationBaseProcessor

type ChatProcessor struct {    *lhttp.BaseProcessor}

Implement three interfaces, what to do when the connection is open, what to do when the message arrives.

type ChatProcessor struct {}func (p ChatProcessor)OnOpen(h *WsHandler) {    //your logic}func (p ChatProcessor)OnClose(h *WsHandler) {    //your logic}func (p ChatProcessor)OnMessage(h *WsHandler) {    //your logic}

Register your processor, here with the chat message body, that is chat对应 , this processor will only process LHTTP/1.0 chat\r\n.... this kind of message.

lhttp.Regist("chat",&ChatProcessor{&lhttp.BaseProcessor{}})

If the command code is "chat" Chatprocessor will handle it.

Here, for example, you receive a message and return it directly:

func (p *ChatProcessor)OnMessage(h *WsHandler) {    h.Send(h.GetBody())}

Start the server

http.Handler("/echo",lhttp.Handler(lhttp.StartServer))http.ListenAndServe(":8081")

A complete example of a back-shot:

type ChatProcessor struct {    *lhttp.BaseProcessor}func (p *ChatProcessor) OnMessage (h *lhttp.WsHandler) {    log.Print("on message :", h.GetBody())    h.Send(h.GetBody())}func main(){    lhttp.Regist("chat", &ChatProcessor{&lhttp.BaseProcessor{}})    http.Handle("/echo",lhttp.Handler(lhttp.StartServer))    http.ListenAndServe(":8081",nil)}

Subscribe/Publish

Here's how easy it is to develop a timely communication application with Lhttp

Let's say there are two clients, such as browser applications.

CLIENT1:

LHTTP/1.0 command\r\nsubscribe:channelID\r\n\r\nbody optional

Client1 sends the string as above through WebSocket to Lhttp, subscribes to thechannelId

CLIENT2:

LHTTP/1.0 command\r\npublish:channelID\r\n\r\nbody require

Client2 sends a message to the lhttp by sending it as a string on the WebSocket channelID . Because Client1 subscribes to Channelid, CLIENT1 will receive this message.

Client1 do not want to receive the message, then send the following string to the server can:

LHTTP/1.0 command\r\nunsubscribe:channelID\r\n\r\nbody optional

Subscription/release is lhttp built-in functionality, the service side line of code to obtain this service without writing, only need to use a specific header subscribe , publish andunsubscribe

Subscribe to multiple chat rooms at the same time.

LHTTP/1.0 chat\r\nsubscribe:channelID1 channelID2 channelID3\r\n\r\n

Publishing messages using HTTP

URL:/publish.
Method: POST.
HTTP body: Entire lhttp message
For example I want the send a message to the WHO subscribe channel_test by HTTP.
If I want to send a message to the person who subscribed to channel_test.

    resp,err := http.POST("https://www.yourserver.com/publish", "text/plain",    "LHTTP/1.0 chat\r\npublish:channel_test\r\n\r\nhello channel_test guys!")

This encapsulates a better tool Publish Tools.go

//func Publish(channelID []string, command string, header map[string]string, body string) (err error) {//}//send message to who subscribe mike.Publish("mike", "yourCommand", nil, "hello mike!")

Upstream server

Upstream header allows Lhttp to send a message to the upstream HTTP server.

LHTTP/1.0 command\r\nupstream:POST http://www.xxx.com\r\n\r\nbody

In the case of the Post method, Lhttp sends the entire message body as HTTP body to http://www.xxx.com
If it is get,lhttp will ignore the message body

LHTTP/1.0 command\r\nupstream:GET http://www.xxx.com?user=user_a&age=26\r\n\r\nbody

What is the use of upstream:

If we do not want to change the Lhttp code, but want to store chat records.

A good decoupling can be achieved through the upstream:

and HTTP server can be implemented in other languages.

        +----+                  +----+        |jack|                  |mike|        +----+                  +----+         |_____________    _______|                       |  |                   +------------+                   |lhttp server|                   +------------+                         |(http request with chat record)                         V                   +------------+                   | http server|  upstream server(http://www.xxx.com/record)                   +------------+                   (save chat record)    

Jack

LHTTP/1.0 chat\r\nupstream:POST http://www.xxx.com/record\r\npublish:channel_mike\r\n\r\nhello mike,I am jack

Mike

LHTTP/1.0 chat\r\nsubscribe:channel_mike\r\n\r\n

So Jack publish the message when not only Mike can receive, back-end upstream server can also receive, we can process the message store logic in the back-end server, such as the message

Stored in an ordered collection of Redis.

Chunked message

Imagine a message that has both a picture and text and a voice. Lhttp's multipart first solved the problem

LHTTP/1.0 upload\r\nmultipart:0 56\r\n\r\ncontent-type:text/json\r\n\r\n{filename:file.txt,fileLen:5}content-type:text/plain\r\n\r\nhello
content-type:text/json\r\n\r\n{filename:file.txt,fileLen:5}content-type:text/plain\r\n\r\nhello^                                                          ^|<---------------------first part------------------------->|<---------second part------------>|0                                                          56                           

HTTP is implemented using Boundry, and Lhttp uses an offset to identify the tiles, which is more efficient and does not need to traverse the entire message body.

How to get chunked messages

such as client messages are as follows:

LHTTP/1.0 upload\r\nmultipart:0 14\r\n\r\nk1:v1\r\n\r\nbody1k2:v2\r\n\r\nbody2

Server-side code, the message exists in the list:

type UploadProcessor struct {    *lhttp.BaseProcessor}func (*UploadProcessor) OnMessage(ws *lhttp.WsHandler) {    for m := ws.GetMultipart(); m != nil; m = m.GetNext() {        log.Print("multibody:", m.GetBody(), " headers:", m.GetHeaders())    }}//don't forget to tegist your command processorlhttp.Regist("upload", &UploadProcessor{&lhttp.BaseProcessor{}})

First Filter Module development

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.