Node、Python、Go中的websocket

零 Python教程评论129字数 8421阅读28分4秒阅读模式

Node、Python、Go中的websocket

在之前的文章中,我们已经多次探讨了WebSocket的各种实现和应用,尤其是使用Node.js生态系统来演示。然而,为了让大家更全面地了解不同编程语言在实现WebSocket服务器时的特点和优势,今天我们将使用Node.js、Python和Golang这三种流行的编程语言,分别对比实现同样的需求。文章源自灵鲨社区-https://www.0s52.com/bcjc/pythonjc/16767.html

本文将通过具体的代码示例,展示如何在这些语言中进行连接管理、消息广播、心跳检测和实时数据推送等常见任务。最后,我们还将对这三种语言的实现进行对比,分析它们的优缺点和适用场景。无论你是初学者还是有经验的开发者,希望通过这篇文章,你能掌握在不同编程语言中实现WebSocket服务器的技巧和最佳实践,从而为你的实时通信应用奠定坚实的技术基础。文章源自灵鲨社区-https://www.0s52.com/bcjc/pythonjc/16767.html

Node.js实现WebSocket服务器

1. 基本代码示例

javascript

复制代码
  1. const WebSocket = require('ws');
  2. const server = new WebSocket.Server({ port: 8080 });
  3. server.on('connection', (ws) => {
  4. console.log('新的客户端已连接');
  5. ws.on('message', (message) => {
  6. console.log(`收到消息: ${message}`);
  7. // 回显收到的消息给客户端
  8. ws.send(`你说: ${message}`);
  9. });
  10. ws.on('close', () => {
  11. console.log('客户端已断开连接');
  12. });
  13. ws.send('欢迎连接到WebSocket服务器!');
  14. });
  15. console.log('WebSocket服务器运行在ws://localhost:8080');

2. 连接管理和消息广播

javascript

复制代码
  1. const WebSocket = require('ws');
  2. const server = new WebSocket.Server({ port: 8080 });
  3. const clients = new Set();
  4. server.on('connection', (ws) => {
  5. clients.add(ws);
  6. console.log('新的客户端已连接');
  7. ws.on('message', (message) => {
  8. console.log(`收到消息: ${message}`);
  9. // 将消息广播给所有连接的客户端
  10. clients.forEach((client) => {
  11. if (client !== ws && client.readyState === WebSocket.OPEN) {
  12. client.send(message);
  13. }
  14. });
  15. });
  16. ws.on('close', () => {
  17. clients.delete(ws);
  18. console.log('客户端已断开连接');
  19. });
  20. ws.send('欢迎连接到WebSocket服务器!');
  21. });
  22. console.log('WebSocket服务器运行在ws://localhost:8080');

3. 心跳检测和重连机制

javascript

复制代码
  1. const WebSocket = require('ws');
  2. const server = new WebSocket.Server({ port: 8080 });
  3. server.on('connection', (ws) => {
  4. ws.isAlive = true;
  5. ws.on('pong', () => {
  6. ws.isAlive = true;
  7. });
  8. ws.on('message', (message) => {
  9. console.log(`收到消息: ${message}`);
  10. ws.send(`你说: ${message}`);
  11. });
  12. ws.on('close', () => {
  13. console.log('客户端已断开连接');
  14. });
  15. ws.send('欢迎连接到WebSocket服务器!');
  16. });
  17. const interval = setInterval(() => {
  18. server.clients.forEach((ws) => {
  19. if (!ws.isAlive) return ws.terminate();
  20. ws.isAlive = false;
  21. ws.ping();
  22. });
  23. }, 30000);
  24. server.on('close', () => {
  25. clearInterval(interval);
  26. });
  27. console.log('WebSocket服务器运行在ws://localhost:8080');

4. 实时数据推送

javascript

复制代码
  1. const WebSocket = require('ws');
  2. const server = new WebSocket.Server({ port: 8080 });
  3. server.on('connection', (ws) => {
  4. console.log('新的客户端已连接');
  5. const sendData = () => {
  6. if (ws.readyState === WebSocket.OPEN) {
  7. const data = { timestamp: new Date(), value: Math.random() };
  8. ws.send(JSON.stringify(data));
  9. }
  10. };
  11. const interval = setInterval(sendData, 1000);
  12. ws.on('close', () => {
  13. clearInterval(interval);
  14. console.log('客户端已断开连接');
  15. });
  16. ws.send('欢迎连接到WebSocket服务器!');
  17. });
  18. console.log('WebSocket服务器运行在ws://localhost:8080');

Python实现WebSocket服务器

1. 基本代码示例

python

复制代码
  1. import asyncio
  2. import websockets
  3. async def handler(websocket, path):
  4. print("新的客户端已连接")
  5. try:
  6. async for message in websocket:
  7. print(f"收到消息: {message}")
  8. await websocket.send(f"你说: {message}")
  9. except websockets.exceptions.ConnectionClosed:
  10. print("客户端已断开连接")
  11. start_server = websockets.serve(handler, "localhost", 8080)
  12. asyncio.get_event_loop().run_until_complete(start_server)
  13. asyncio.get_event_loop().run_forever()
  14. print('WebSocket服务器运行在ws://localhost:8080')

2. 连接管理和消息广播

python

复制代码
  1. import asyncio
  2. import websockets
  3. clients = set()
  4. async def handler(websocket, path):
  5. clients.add(websocket)
  6. print("新的客户端已连接")
  7. try:
  8. async for message in websocket:
  9. print(f"收到消息: {message}")
  10. # 将消息广播给所有连接的客户端
  11. await asyncio.wait([client.send(message) for client in clients if client != websocket])
  12. except websockets.exceptions.ConnectionClosed:
  13. print("客户端已断开连接")
  14. finally:
  15. clients.remove(websocket)
  16. start_server = websockets.serve(handler, "localhost", 8080)
  17. asyncio.get_event_loop().run_until_complete(start_server)
  18. asyncio.get_event_loop().run_forever()
  19. print('WebSocket服务器运行在ws://localhost:8080')

3. 心跳检测和重连机制

python

复制代码
  1. import asyncio
  2. import websockets
  3. clients = set()
  4. async def handler(websocket, path):
  5. clients.add(websocket)
  6. print("新的客户端已连接")
  7. try:
  8. async for message in websocket:
  9. print(f"收到消息: {message}")
  10. await websocket.send(f"你说: {message}")
  11. except websockets.exceptions.ConnectionClosed:
  12. print("客户端已断开连接")
  13. finally:
  14. clients.remove(websocket)
  15. async def heartbeat():
  16. while True:
  17. for client in clients.copy():
  18. try:
  19. await client.ping()
  20. except websockets.exceptions.ConnectionClosed:
  21. clients.remove(client)
  22. await asyncio.sleep(30)
  23. start_server = websockets.serve(handler, "localhost", 8080)
  24. asyncio.get_event_loop().run_until_complete(start_server)
  25. asyncio.get_event_loop().run_until_complete(heartbeat())
  26. print('WebSocket服务器运行在ws://localhost:8080')

4. 实时数据推送

python

复制代码
  1. import asyncio
  2. import websockets
  3. import json
  4. from datetime import datetime
  5. import random
  6. async def handler(websocket, path):
  7. print("新的客户端已连接")
  8. try:
  9. while True:
  10. data = {"timestamp": datetime.now().isoformat(), "value": random.random()}
  11. await websocket.send(json.dumps(data))
  12. await asyncio.sleep(1)
  13. except websockets.exceptions.ConnectionClosed:
  14. print("客户端已断开连接")
  15. start_server = websockets.serve(handler, "localhost", 8080)
  16. asyncio.get_event_loop().run_until_complete(start_server)
  17. asyncio.get_event_loop().run_forever()
  18. print('WebSocket服务器运行在ws://localhost:8080')

Golang实现WebSocket服务器

1. 基本代码示例

go

复制代码
  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gorilla/websocket"
  6. )
  7. var upgrader = websocket.Upgrader{
  8. ReadBufferSize: 1024,
  9. WriteBufferSize: 1024,
  10. }
  11. func handler(w http.ResponseWriter, r *http.Request) {
  12. conn, err := upgrader.Upgrade(w, r, nil)
  13. if err != nil {
  14. fmt.Println(err)
  15. return
  16. }
  17. defer conn.Close()
  18. for {
  19. messageType, message, err := conn.ReadMessage()
  20. if err != nil {
  21. fmt.Println(err)
  22. break
  23. }
  24. fmt.Printf("收到消息: %sn", message)
  25. if err := conn.WriteMessage(messageType, message); err != nil {
  26. fmt.Println(err)
  27. break
  28. }
  29. }
  30. }
  31. func main() {
  32. http.HandleFunc("/", handler)
  33. fmt.Println("WebSocket服务器运行在ws://localhost:8080")
  34. http.ListenAndServe(":8080", nil)
  35. }

2. 连接管理和消息广播

go

复制代码
  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "sync"
  6. "github.com/gorilla/websocket"
  7. )
  8. var upgrader = websocket.Upgrader{
  9. ReadBufferSize: 1024,
  10. WriteBufferSize: 1024,
  11. }
  12. var clients = make(map[*websocket.Conn]bool)
  13. var mutex = &sync.Mutex{}
  14. func handler(w http.ResponseWriter, r *http.Request) {
  15. conn, err := upgrader.Upgrade(w, r, nil)
  16. if err != nil {
  17. fmt.Println(err)
  18. return
  19. }
  20. defer conn.Close()
  21. mutex.Lock()
  22. clients[conn] = true
  23. mutex.Unlock()
  24. for {
  25. _, message, err := conn.ReadMessage()
  26. if err != nil {
  27. fmt.Println(err)
  28. break
  29. }
  30. fmt.Printf("收到消息: %sn", message)
  31. mutex.Lock()
  32. for client := range clients {
  33. if client != conn {
  34. if err := client.WriteMessage(websocket.TextMessage, message); err != nil {
  35. fmt.Println(err)
  36. client.Close()
  37. delete(clients, client)
  38. }
  39. }
  40. }
  41. mutex.Unlock()
  42. }
  43. mutex.Lock()
  44. delete(clients, conn)
  45. mutex.Unlock()
  46. }
  47. func main() {
  48. http.HandleFunc("/", handler)
  49. fmt.Println("WebSocket服务器运行在ws://localhost:8080")
  50. http.ListenAndServe(":8080", nil)
  51. }

3. 心跳检测和重连机制

go

复制代码
  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "github.com/gorilla/websocket"
  7. )
  8. var upgrader = websocket.Upgrader{
  9. ReadBufferSize: 1024,
  10. WriteBufferSize: 1024,
  11. }
  12. func handler(w http.ResponseWriter, r *http.Request) {
  13. conn, err := upgrader.Upgrade(w, r, nil)
  14. if err != nil {
  15. fmt.Println(err)
  16. return
  17. }
  18. defer conn.Close()
  19. conn.SetReadLimit(512)
  20. conn.SetReadDeadline(time.Now().Add(60 * time.Second))
  21. conn.SetPongHandler(func(string) error { conn.SetReadDeadline(time.Now().Add(60 * time.Second)); return nil })
  22. ticker := time.NewTicker(30 * time.Second)
  23. defer ticker.Stop()
  24. done := make(chan struct{})
  25. go func() {
  26. defer close(done)
  27. for {
  28. _, message, err := conn.ReadMessage()
  29. if err != nil {
  30. fmt.Println(err)
  31. return
  32. }
  33. fmt.Printf("收到消息: %sn", message)
  34. }
  35. }()
  36. for {
  37. select {
  38. case <-done:
  39. return
  40. case <-ticker.C:
  41. if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
  42. fmt.Println(err)
  43. return
  44. }
  45. }
  46. }
  47. }
  48. func main() {
  49. http.HandleFunc("/", handler)
  50. fmt.Println("WebSocket服务器运行在ws://localhost:8080")
  51. http.ListenAndServe(":8080", nil)
  52. }

4. 实时数据推送

go

复制代码
  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "math/rand"
  7. "github.com/gorilla/websocket"
  8. )
  9. var upgrader = websocket.Upgrader{
  10. ReadBufferSize: 1024,
  11. WriteBufferSize: 1024,
  12. }
  13. func handler(w http.ResponseWriter, r *http.Request) {
  14. conn, err := upgrader.Upgrade(w, r, nil)
  15. if err != nil {
  16. fmt.Println(err)
  17. return
  18. }
  19. defer conn.Close()
  20. ticker := time.NewTicker(1 * time.Second)
  21. defer ticker.Stop()
  22. for {
  23. select {
  24. case <-ticker.C:
  25. data := fmt.Sprintf(`{"timestamp": "%s", "value": %f}`, time.Now().Format(time.RFC3339), rand.Float64())
  26. if err := conn.WriteMessage(websocket.TextMessage, []byte(data)); err != nil {
  27. fmt.Println(err)
  28. return
  29. }
  30. }
  31. }
  32. }
  33. func main() {
  34. http.HandleFunc("/", handler)
  35. fmt.Println("WebSocket服务器运行在ws://localhost:8080")
  36. http.ListenAndServe(":8080", nil)
  37. }

对比总结

1. 代码简洁性
  • Node.js:
    • 使用ws库,代码简洁,适合快速开发。
    • 异步处理比较直观,适合处理大量并发连接。
  • Python:
    • 使用websockets库,代码清晰易读。
    • 通过asyncio进行异步处理,适合高并发场景。
  • Golang:
    • 使用gorilla/websocket库,代码稍微复杂一些,但性能优越。
    • 原生支持并发处理,适合高性能需求。
2. 性能
  • Node.js:
    • 单线程异步I/O,适合I/O密集型应用。
    • 由于是单线程,需要注意CPU密集型任务的处理。
  • Python:
    • 异步处理性能较好,适合I/O密集型和高并发应用。
    • 对于CPU密集型任务,可能需要借助多进程或其他优化手段。
  • Golang:
    • 原生支持多线程和并发处理,性能优越。
    • 适合高并发、高性能的应用场景。
3. 开发体验
  • Node.js:
    • 丰富的社区资源和第三方库,开发体验良好。
    • 需要掌握异步编程模型。
  • Python:
    • 代码简洁,语法易于理解,开发体验良好。
    • 需要掌握异步编程和asyncio库。
  • Golang:
    • 语法简洁,编译型语言,开发体验良好。
    • 需要掌握并发编程和Goroutine的使用。
4. 适用场景
  • Node.js:
    • 适合构建实时通信应用、聊天应用和WebSocket服务器。
    • 适合快速开发和原型设计。
  • Python:
    • 适合构建实时数据推送、WebSocket服务器和高并发应用。
    • 适合数据处理和科学计算场景。
  • Golang:
    • 适合构建高性能WebSocket服务器和实时通信应用。
    • 适合高并发、高性能的企业级应用。

总结来说,选择哪种语言实现WebSocket服务器取决于具体的应用场景和性能需求。Node.js适合快速开发和I/O密集型应用,Python适合高并发和数据处理应用,而Golang则适合高性能和高并发的应用场景。希望这些代码示例和对比总结对你有所帮助。文章源自灵鲨社区-https://www.0s52.com/bcjc/pythonjc/16767.html 文章源自灵鲨社区-https://www.0s52.com/bcjc/pythonjc/16767.html

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/pythonjc/16767.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论