Golang Web应用开发入门指南
Golang Web应用开发入门指南 大家好:
我想构建一个能够从网页应用向设备发送控制命令的Web应用。 有人建议我使用Go语言配合Angular框架。
关于这一点,谁能提供更清晰的指导?
非常感谢。
我无法运行任何示例,也许Safari不支持WebAssembly?
我认为Safari确实支持WebAssembly。
gioui.org 首页上的演示能正常运行吗?
我刚刚看了一下,我会进行更深入的研究,但它看起来很有趣,并且也有一个Linux平台的解决方案。
我讨厌用 JavaScript 写代码,所以我会选择 Go WebAssembly 这条路。
你可以用这个 https://gioui.org/ 来构建用户界面,这样它就能在浏览器中运行,也能作为原生应用运行。
什么样的控制命令?如果只是点击几个按钮,那么使用 Angular 可能就有点大材小用了。
你也可以用 Go 配合 WebAssembly 来编写前端——这是我写的一个简单游戏:https://www.craig-wood.com/nick/oxo3dwasm/
嗨,尼克 我有一个运行在NUC上的REST API服务器,它控制着各种连接的设备,比如视频编解码器。要让输入1路由到显示器,你(通过telnet)需要写入类似 - join 1,3 的命令。
因此,我想开发一个Web应用程序,用来显示输入编解码器和输出编解码器。用户选择输入,然后点击输出,从而通过API服务器发起命令来实现路由。
这样说得通吗?
对于使用Go构建Web应用向设备发送控制命令,这里是一个完整的实现方案:
后端Go实现
package main
import (
"encoding/json"
"log"
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
)
// 设备控制命令结构
type DeviceCommand struct {
DeviceID string `json:"device_id"`
Command string `json:"command"`
Parameter string `json:"parameter,omitempty"`
}
// 设备状态响应
type DeviceResponse struct {
DeviceID string `json:"device_id"`
Status string `json:"status"`
Timestamp time.Time `json:"timestamp"`
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// WebSocket连接处理
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("WebSocket升级失败: %v", err)
return
}
defer conn.Close()
for {
// 读取前端发送的命令
_, message, err := conn.ReadMessage()
if err != nil {
log.Printf("读取消息失败: %v", err)
break
}
var cmd DeviceCommand
if err := json.Unmarshal(message, &cmd); err != nil {
log.Printf("解析命令失败: %v", err)
continue
}
// 处理设备控制逻辑
response := processDeviceCommand(cmd)
// 发送响应回前端
respJSON, _ := json.Marshal(response)
if err := conn.WriteMessage(websocket.TextMessage, respJSON); err != nil {
log.Printf("发送响应失败: %v", err)
break
}
}
}
func processDeviceCommand(cmd DeviceCommand) DeviceResponse {
// 这里实现实际的设备控制逻辑
// 例如:通过串口、TCP/IP、MQTT等方式控制设备
return DeviceResponse{
DeviceID: cmd.DeviceID,
Status: "命令执行成功",
Timestamp: time.Now(),
}
}
// HTTP API端点
func sendCommandHandler(w http.ResponseWriter, r *http.Request) {
var cmd DeviceCommand
if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil {
http.Error(w, "无效的请求数据", http.StatusBadRequest)
return
}
// 执行设备控制
response := processDeviceCommand(cmd)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func main() {
r := mux.NewRouter()
// 静态文件服务(Angular应用)
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./dist")))
// API路由
api := r.PathPrefix("/api").Subrouter()
api.HandleFunc("/command", sendCommandHandler).Methods("POST")
api.HandleFunc("/ws", handleWebSocket)
// 启动服务器
log.Println("服务器启动在 :8080")
log.Fatal(http.ListenAndServe(":8080", r))
}
前端Angular服务示例
// device.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
export interface DeviceCommand {
device_id: string;
command: string;
parameter?: string;
}
export interface DeviceResponse {
device_id: string;
status: string;
timestamp: string;
}
@Injectable({
providedIn: 'root'
})
export class DeviceService {
private apiUrl = 'http://localhost:8080/api';
private wsUrl = 'ws://localhost:8080/api/ws';
private socket$: WebSocketSubject<any>;
private messages$: Subject<DeviceResponse> = new Subject();
constructor(private http: HttpClient) {
this.connectWebSocket();
}
private connectWebSocket(): void {
this.socket$ = webSocket(this.wsUrl);
this.socket$.subscribe(
(response: DeviceResponse) => {
this.messages$.next(response);
},
(error) => {
console.error('WebSocket错误:', error);
setTimeout(() => this.connectWebSocket(), 5000);
}
);
}
// HTTP方式发送命令
sendCommandHttp(command: DeviceCommand): Observable<DeviceResponse> {
return this.http.post<DeviceResponse>(`${this.apiUrl}/command`, command);
}
// WebSocket方式发送命令
sendCommandWs(command: DeviceCommand): void {
this.socket$.next(command);
}
// 接收设备响应
getDeviceResponses(): Observable<DeviceResponse> {
return this.messages$.asObservable();
}
}
项目结构
project/
├── backend/
│ ├── main.go
│ ├── go.mod
│ └── go.sum
├── frontend/
│ ├── src/
│ │ ├── app/
│ │ │ ├── device.service.ts
│ │ │ └── device-control.component.ts
│ │ └── ...
│ └── angular.json
└── docker-compose.yml
设备通信实现示例
// 通过TCP控制设备
func controlDeviceViaTCP(cmd DeviceCommand) error {
conn, err := net.Dial("tcp", "device-ip:port")
if err != nil {
return err
}
defer conn.Close()
// 发送控制指令
commandStr := fmt.Sprintf("%s:%s\n", cmd.Command, cmd.Parameter)
_, err = conn.Write([]byte(commandStr))
return err
}
// 通过MQTT控制设备
func controlDeviceViaMQTT(cmd DeviceCommand) error {
opts := mqtt.NewClientOptions().AddBroker("tcp://mqtt-broker:1883")
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
return token.Error()
}
topic := fmt.Sprintf("devices/%s/control", cmd.DeviceID)
payload, _ := json.Marshal(map[string]string{
"command": cmd.Command,
"param": cmd.Parameter,
})
token := client.Publish(topic, 0, false, payload)
token.Wait()
return token.Error()
}
这个架构提供了HTTP API和WebSocket两种通信方式,Angular前端可以通过服务类与Go后端交互,实现实时设备控制。

