This is a creation in Article, where the information may have evolved or changed.
Modern web applications are becoming richer and more complex. A fun and vibrant experience like this is popular with users. The user does not need to make a call to the server, or refreshes the browser, allowing the page to be updated in real time. Early developers relied on AJAX to create applications with near real-time experience. Now they can use WebSockets to create fully real-time applications.
In this tutorial we will use the Go programming language and WebSockets to create a live chat application. The front end will be written using HTML5 and Vuejs. This content requires you to have a basic understanding of the Go language, JavaScript, and HTML5, preferably with a little bit of experience using VUEJS.
To use go, you can take a look at the great interactive tutorials on the official GO website:
Https://tour.golang.org/welcome/1
To use Vue, you can take a look at the excellent series of video tutorials available on the Jeffrey-laracasts:
Https://laracasts.com/series/learn-vue-2-step-by-step
Leoxu translated 5 months ago 0 People top Top Well translated!
What is WebSocket?
Typically, a WEB application uses one or more requests to provide external services to an HTTP server. The client software is typically a Web browser sending a request to the server, and the server sends back a response. The response is usually HTML content, which is rendered as a page by the browser. Style sheets, JavaScript code, and images can also be sent back in response to complete the entire Web page. Each request and response is part of a specific, separate connection, and a large web site such as Facebook can actually produce hundreds of of these connections in order to render a single page.
AJAX works exactly the same way. Using JavaScript, developers can request a small piece of information from the HTTP server and then update some pages based on the response. This can be done without refreshing the browser, but there are still some limitations.
tocy translated 5 months ago 2 people top Top Well translated!
Each HTTP request/response connection is closed after it has been responded to, so any new information must be created to create another connection. If no new request is sent to the server, it is unaware that the client is looking for new information. One technique that allows AJAX applications to look like real-time is to periodically cycle through AJAX requests. After the time interval has been set, the application can resend the request to the server to see if any updates need to be fed back to the browser. This is better for small applications, but not efficient. This is where WebSockets comes in handy.
WebSockets is part of the recommended standards that are created by the Internet Engineering Task Force (IETF). The complete technical specification of the WebSockets implementation is described in detail in RFC6455. The following is an excerpt of the document definition WebSocket:
The WebSocket protocol is used for communication between the client code and the remote host, where the client code is a non-credit code in a controlled environment
In other words, WebSocket is a always-on connection that allows the client and server to send messages spontaneously and back. The server can push new information to the client when necessary, and the client can perform the same operation on the server.
tocy translated 5 months ago 0 People top Top Well translated!
The WebSockets in JavaScript
Most modern browsers support WebSockets in their JavaScript implementations. To start a WebSocket connection from the browser, you can use the simple WebSocket JavaScript object as follows:
var ws = new Websocket ("Ws://example.com/ws");
The only parameter you need is a url,websocket connection that connects to the server through this URL. The request is actually an HTTP request, but we use "ws://" or "wss://" for secure connection. This allows the server to know that we are trying to create a new WebSocket connection. The server then "upgrades" the connection between the client and the service to a permanent two-way connection.
Once the new WebSocket object is created and the connection is successfully created, we can send the text to the server using the Send () method and define a handler function on the WebSocket "OnMessage" property to process the message sent from the server. The specific logic is explained in the following chat application code.
tocy translated 5 months ago 0 People top Top Well translated!
WebSockets in Go
WebSockets is not included in the Go standard library, but fortunately there are some nice third-party packages that make WebSockets easy to use. In this example, we will use a package called "Gorilla/websocket", which is part of the popular Gorilla Toolkit package collection and is used to create a WEB application in Go. Please run the following command to install:
$ go Get github.com/gorilla/websocket
tocy translated 5 months ago 0 People top Top Well translated!
Build Server
The first part of this application is the server. This is a simple HTTP server that handles requests. It will provide us with HTML5 and JavaScript code, as well as establish the client's WebSocket connection. In addition, the server will track each WebSocket connection and send chat information from one client to all other clients via the WebSocket connection. Create a new empty directory first, and then create a "src" and "public" directory in that directory. Create a file named "Main.go" in the "src" directory.
Set up the server first to make some settings. We start the application like all Go applications and define the package namespace, in this case, "main". Next we import some useful packages. Both "Log" and "Net/http" are part of the standard library and will be used for logging and creating a simple HTTP server. The final package "Github.com/gorilla/websocket" will help us easily create and use websocket connections.
Package Mainimport ( "Log" "Net/http" "Github.com/gorilla/websocket")
tocy translated 5 months ago 0 People top Top Well translated!
The following two lines of code are global variables that will be used elsewhere in the application. The practice of global variables is poor, but for the sake of simplicity we have used them. The first variable is a map map whose key corresponds to a pointer to WebSocket, whose value is a Boolean value. We do not actually need this value, but the mapped data structure used requires a mapped value, which makes it easier to add and remove items.
The second variable is a queue that is used by the client to send messages, playing the role of the channel. In the later code, we define a goroutine to read the new messages from this channel and send them to other clients connected to the server.
var clients = make (map[*websocket. Conn]bool)//connected Clientsvar broadcast = make (chan Message)//Broadcast channel
Next we create an instance of Upgrader. This is just an object, it has a few methods, these methods can get a normal HTTP link and then upgrade it to a WebSocket, later there will be related code introduction.
Configure the Upgradervar upgrader = WebSocket. upgrader{}
Finally we will define an object to manage the message, the data structure is simple, with some string attributes, an email address, a user name, and the actual message content. We will use email to demonstrate the unique identity provided by the Gravatar service.
Leoxu translated 5 months ago 1 people top Top Well translated!
The text that is contained in the anti-quotation marks is the metadata that Go requires when it is serialized and deserialized between the object and the JSON.
Define our message objecttype message struct { email string ' JSON: "email" ' Username string ' JSON: " Username "' message string ' JSON:" message "' }
The main entry for the Go application is always the "main ()" function. The code is very concise. We first create a static file service and bind it to the "/" route so that users can see index.html and other resources when they visit the site. In this example we have a "app.js" file that holds the JavaScript code and a "style.css" file that saves the style.
Func Main () {//Create a Simple file server fs: = http. Fileserver (http. Dir (".. /public ")) http. Handle ("/", FS)
The next route we want to define is "/ws", where the request to start WebSocket is processed. We first pass the name of a function to the handler function, "Handleconnections", and then define the function later.
Func main () {...//Configure websocket route http. Handlefunc ("/ws", handleconnections)
The next step is to launch a Go program called "Handlemessages". This is a parallel process that runs independently of the application and other parts, obtains messages from the broadcast channel, and passes through the WebSocket connections of each client. Parallelism is a powerful feature of Go. The content of how it works is beyond the scope of this article, but you can check out the official Go tutorial website yourself. If you are familiar with JavaScript, you can associate a parallel process with a Go program that runs as a background procedure, or an asynchronous function of JavaScript.
Func main () {...//Start listening for incoming chat messages go handlemessages ()
border town translation in 5 months ago 1 people top Top Well translated!
Finally, we print a secondary message to the console and start the Web service. If an error occurs, we record it and exit the application.
Func main () {...//Start the server on localhost, Port 8000 and log any errors log. PRINTLN ("HTTP server started on:8000") Err: = http. Listenandserve (": 8000", nil) if err! = Nil {log. Fatal ("Listenandserve:", Err)}}
Next we create a function to process the incoming WebSocket connection. First we use the upgraded "Upgrade ()" method to change the initial GET request to make it a full WebSocket. If an error occurs, log it down, but do not exit. Also note the defer statement, which informs Go to close WebSocket when the function returns. This is a good way to save us a lot of "Close ()" statements that might appear before returning functions in different branches.
Func handleconnections (w http. Responsewriter, R *http. Request) {//Upgrade initial GET request to a websocket ws, ERR: = Upgrader. Upgrade (W, R, nil) if err! = Nil {log. Fatal (ERR)}//Make sure we close the connection when the function returns defer WS. Close ()
The new client is then added to the global "clients" mapping table for registration, which was created earlier.
Func handleconnections (w http. Responsewriter, R *http. Request) {...//Register our new client Clients[ws] = True
The final step is an infinite loop that waits for a new message to be written to WebSocket, deserializes it from JSON to a Message object, and feeds the broadcast channel. However, the "handlemessages ()" Go program can send it to other clients in the connection.
border town translation in 5 months ago 2 people top Top Well translated! If the data read from the socket is wrong, we assume that the client has been disconnected for some reason. We log the error and remove the client from the global "clients" mapping table, so that we do not continue to try to communicate with it.
In addition, the HTTP route handler function has been run as goroutines. This allows the HTTP server to handle multiple incoming connections without waiting for another connection to complete.
Func handleconnections (w http. Responsewriter, r *http. Request) { ... for { var msg message // read in a new message as json and map it to a Message object err := ws. Readjson (&msg) if err != nil { log. Printf ("Error: %v", err) delete (CLIENTS,&NBSP;WS) break } // send the newly received message to the broadcast channel broadcast <- msg }}
The last part of the server is "Handlemessages ()"Function. This is a simple loop that reads the data continuously from "broadcast" and then propagates the message to the client through the respective WebSocket connection. Similarly, if an error occurs when writing to Websocket, we will close the connection and move it from "Clients" mappingdeleted in the.
Func handlemessages () { for { // grab the next message from the broadcast channel msg := <-broadcast // Send it out to every client that is currently connected for client := range clients { err := client. Writejson (msg) if err != nil { log. Printf ("Error: %v", err) client. Close () delete (Clients, client) } } }}
Darwin translated 5 months ago 1 people top Top Well translated!