Полный код этого раздела:GitHub
Эта статья является второй частью этой серии статей об использовании ReactJS и Go для создания приложения чата. Вы можете найти часть 1 здесь -Инициализировать настройки
Теперь, когда мы установили базовый интерфейс и серверную часть, нам нужно улучшить некоторые функции.
В этом разделе мы реализуем сервер на основе WebSocket.
К концу этой серии руководств у нас будет интерфейсное приложение, которое может взаимодействовать с серверной частью в двух направлениях.
Служить
мы можем использоватьgithub.com/gorilla/websocket
Пакет для настройки службы WebSocket и обработки операций чтения и записи на подключении Websocket.
Это должно быть в нашемbackend/
каталог, чтобы установить его, выполнив эту команду:
$ go get github.com/gorilla/websocket
После того, как мы успешно установили этот пакет, мы можем приступить к созданию нашего веб-сервиса. Сначала мы создаем очень простойnet/http
Служить:
package main
import (
"fmt"
"net/http"
)
func setupRoutes() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Simple Server")
})
}
func main() {
setupRoutes()
http.ListenAndServe(":8080", nil)
}
позвонивgo run main.go
запустить службу, которая будет слушатьhttp://localhost:8080. Если вы откроете это соединение в браузере, вы увидите выводSimple Server
.
Протокол веб-сокета
Прежде чем мы начнем писать код, нам нужно понять теорию.
WebSockets могут обмениваться данными в дуплексном режиме через TCP-соединение. Это позволяет нам отправлять и прослушивать сообщения через один сокет TCP, избегая необходимости опрашивать веб-сервер для связи, который выполняет процесс квитирования TCP для каждой операции опроса.
Веб-сокеты значительно уменьшают пропускную способность сети, необходимую приложению, и позволяют нам поддерживать большое количество клиентов на одном экземпляре сервера.
соединять
У WebSockets определенно есть некоторые недостатки, которые стоит учитывать. Например, после введения состояния оно становится более сложным при масштабировании приложения на несколько экземпляров.
В этом сценарии следует учитывать и другие случаи, например сохранение состояния в брокере сообщений или в кэше базы данных/памяти.
выполнить
При реализации службы WebSocket нам необходимо создать конечную точку, а затем обновить соединение конечной точки со стандартного HTTP на WebSocket.
К счастью,gorilla/websocket
Пакет предоставляет функциональные возможности, необходимые для простого обновления соединений HTTP до соединений WebSocket.
Примечание. Вы можете ознакомиться с официальным протоколом WebSocket для получения дополнительной информации:RFC-6455
Создайте сервер WebSocket
Теперь, когда вы поняли теорию, давайте посмотрим, как применить ее на практике. Создаем новую конечную точку/ws
, начнем со стандартаhttp
Конечные точки преобразуются вws
конечная точка.
Эта конечная точка сделает 3 вещи, проверит входящий HTTP-запрос и вернетtrue
чтобы открыть нашу конечную точку для клиента. Затем мы используем определенныйupgrader
Обновление до подключения WebSocket.
Наконец, мы начнем прослушивать входящие сообщения, затем распечатывать их и передавать обратно по тому же соединению. Это позволяет нам аутентифицировать внешнее соединение и отправлять/получать сообщения от только что созданной конечной точки WebSocket:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
// 我们需要定义一个 Upgrader
// 它需要定义 ReadBufferSize 和 WriteBufferSize
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
// 可以用来检查连接的来源
// 这将允许从我们的 React 服务向这里发出请求。
// 现在,我们可以不需要检查并运行任何连接
CheckOrigin: func(r *http.Request) bool { return true },
}
// 定义一个 reader 用来监听往 WS 发送的新消息
func reader(conn *websocket.Conn) {
for {
// 读消息
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
// 打印消息
fmt.Println(string(p))
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
// 定义 WebSocket 服务处理函数
func serveWs(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.Host)
// 将连接更新为 WebSocket 连接
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
}
// 一直监听 WebSocket 连接上传来的新消息
reader(ws)
}
func setupRoutes() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Simple Server")
})
// 将 `/ws` 端点交给 `serveWs` 函数处理
http.HandleFunc("/ws", serveWs)
}
func main() {
fmt.Println("Chat App v0.01")
setupRoutes()
http.ListenAndServe(":8080", nil)
}
Если нет проблем, мы используемgo run main.go
для запуска службы.
клиент
Теперь, когда служба настроена, нам нужно что-то, с чем можно взаимодействовать. Здесь в игру вступает наш интерфейс ReactJS.
Давайте постараемся максимально упростить клиент и определимapi/index.js
Файл, он будет содержать код подключения WebSocket.
// api/index.js
var socket = new WebSocket("ws://localhost:8080/ws");
let connect = () => {
console.log("Attempting Connection...");
socket.onopen = () => {
console.log("Successfully Connected");
};
socket.onmessage = msg => {
console.log(msg);
};
socket.onclose = event => {
console.log("Socket Closed Connection: ", event);
};
socket.onerror = error => {
console.log("Socket Error: ", error);
};
};
let sendMsg = msg => {
console.log("sending msg: ", msg);
socket.send(msg);
};
export { connect, sendMsg };
Итак, в приведенном выше коде мы определяем 2 функции, которые затем экспортируем. соответственноconnect()
а такжеsendMsg(msg)
.
Первая функция,connect()
функция, которая подключается к конечной точке WebSocket и прослушивает, например, с помощьюonopen
Такие события, как успешное подключение. Если он обнаруживает какие-либо проблемы, такие как закрытые сокеты соединения или ошибки, он выводит эти проблемы в консоль браузера.
вторая функция,sendMsg(msg)
функция, которая позволяет нам использоватьsocket.send()
Отправляйте сообщения из внешнего интерфейса в бэкэнд через соединение WebSocket.
Теперь обновляем в проекте ReactApp.js
файл, добавьте паруconnect()
позвонить и создать триггерsendMsg()
функциональный<button />
элемент.
// App.js
import React, { Component } from "react";
import "./App.css";
import { connect, sendMsg } from "./api";
class App extends Component {
constructor(props) {
super(props);
connect();
}
send() {
console.log("hello");
sendMsg("hello");
}
render() {
return (
<div className="App">
<button onClick={this.send}>Hit</button>
</div>
);
}
}
export default App;
использоватьnpm start
После успешной компиляции мы можем увидеть кнопку в браузере, и если мы откроем консоль браузера, мы также увидим, что успешно подключенный сервис WebSocket работает наhttp://localhost:8080.
Вопрос - что происходит при нажатии на эту кнопку? Какой вывод вы видите в консоли браузера и консоли бэкэнда?
Суммировать
На этом вторая часть этой серии заканчивается. Нам удалось создать очень простую службу WebSocket, которая повторяет любое посланное ей сообщение.
Это важный шаг в разработке приложения, и теперь, когда у нас есть базовая структура, мы можем начать думать о реализации основных функций чата и сделать приложение более полезным!
Далее: Часть 3 -Фронтальная реализация
оригинал:учебник edge.net/projects/eat…
автор:Elliot ForbesПереводчик:щелк-щелкКоррезирование:polaris1119
Эта статья написанаGCTTоригинальная компиляция,Перейти на китайский языкЧесть запуска