国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Go語言網(wǎng)絡(luò)編程(socket編程)WebSocket編程

這篇具有很好參考價(jià)值的文章主要介紹了Go語言網(wǎng)絡(luò)編程(socket編程)WebSocket編程。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1、WebSocket編程

1.1.1. webSocket是什么

WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議
WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)
在WebSocket API中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸
需要安裝第三方包:
cmd中:go get -u -v github.com/gorilla/websocket

1.1.2.舉個(gè)聊天室的小例子

在同一級(jí)目錄下新建四個(gè)go文件connection.go|data.go|hub.go|server.go

運(yùn)行

    go run server.go hub.go data.go connection.go

運(yùn)行之后執(zhí)行l(wèi)ocal.html文件

server.go文件代碼

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func main() {
    router := mux.NewRouter()
    go h.run()
    router.HandleFunc("/ws", myws)
    if err := http.ListenAndServe("127.0.0.1:8080", router); err != nil {
        fmt.Println("err:", err)
    }
}

hub.go文件代碼

package main

import "encoding/json"

var h = hub{
    c: make(map[*connection]bool),
    u: make(chan *connection),
    b: make(chan []byte),
    r: make(chan *connection),
}

type hub struct {
    c map[*connection]bool
    b chan []byte
    r chan *connection
    u chan *connection
}

func (h *hub) run() {
    for {
        select {
        case c := <-h.r:
            h.c[c] = true
            c.data.Ip = c.ws.RemoteAddr().String()
            c.data.Type = "handshake"
            c.data.UserList = user_list
            data_b, _ := json.Marshal(c.data)
            c.sc <- data_b
        case c := <-h.u:
            if _, ok := h.c[c]; ok {
                delete(h.c, c)
                close(c.sc)
            }
        case data := <-h.b:
            for c := range h.c {
                select {
                case c.sc <- data:
                default:
                    delete(h.c, c)
                    close(c.sc)
                }
            }
        }
    }
}

data.go文件代碼

package main

type Data struct {
    Ip       string   `json:"ip"`
    User     string   `json:"user"`
    From     string   `json:"from"`
    Type     string   `json:"type"`
    Content  string   `json:"content"`
    UserList []string `json:"user_list"`
}

connection.go文件代碼

package main

import (
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/gorilla/websocket"
)

type connection struct {
    ws   *websocket.Conn
    sc   chan []byte
    data *Data
}

var wu = &websocket.Upgrader{ReadBufferSize: 512,
    WriteBufferSize: 512, CheckOrigin: func(r *http.Request) bool { return true }}

func myws(w http.ResponseWriter, r *http.Request) {
    ws, err := wu.Upgrade(w, r, nil)
    if err != nil {
        return
    }
    c := &connection{sc: make(chan []byte, 256), ws: ws, data: &Data{}}
    h.r <- c
    go c.writer()
    c.reader()
    defer func() {
        c.data.Type = "logout"
        user_list = del(user_list, c.data.User)
        c.data.UserList = user_list
        c.data.Content = c.data.User
        data_b, _ := json.Marshal(c.data)
        h.b <- data_b
        h.r <- c
    }()
}

func (c *connection) writer() {
    for message := range c.sc {
        c.ws.WriteMessage(websocket.TextMessage, message)
    }
    c.ws.Close()
}

var user_list = []string{}

func (c *connection) reader() {
    for {
        _, message, err := c.ws.ReadMessage()
        if err != nil {
            h.r <- c
            break
        }
        json.Unmarshal(message, &c.data)
        switch c.data.Type {
        case "login":
            c.data.User = c.data.Content
            c.data.From = c.data.User
            user_list = append(user_list, c.data.User)
            c.data.UserList = user_list
            data_b, _ := json.Marshal(c.data)
            h.b <- data_b
        case "user":
            c.data.Type = "user"
            data_b, _ := json.Marshal(c.data)
            h.b <- data_b
        case "logout":
            c.data.Type = "logout"
            user_list = del(user_list, c.data.User)
            data_b, _ := json.Marshal(c.data)
            h.b <- data_b
            h.r <- c
        default:
            fmt.Print("========default================")
        }
    }
}

func del(slice []string, user string) []string {
    count := len(slice)
    if count == 0 {
        return slice
    }
    if count == 1 && slice[0] == user {
        return []string{}
    }
    var n_slice = []string{}
    for i := range slice {
        if slice[i] == user && i == count {
            return slice[:count]
        } else if slice[i] == user {
            n_slice = append(slice[:i], slice[i+1:]...)
            break
        }
    }
    fmt.Println(n_slice)
    return n_slice
}

local.html文件代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-701972.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <style>
        p {
            text-align: left;
            padding-left: 20px;
        }
    </style>
</head>
<body>
<div style="width: 800px;height: 600px;margin: 30px auto;text-align: center">
    <h1>www.5lmh.comy演示聊天室</h1>
    <div style="width: 800px;border: 1px solid gray;height: 300px;">
        <div style="width: 200px;height: 300px;float: left;text-align: left;">
            <p><span>當(dāng)前在線:</span><span id="user_num">0</span></p>
            <div id="user_list" style="overflow: auto;">
            </div>
        </div>
        <div id="msg_list" style="width: 598px;border:  1px solid gray; height: 300px;overflow: scroll;float: left;">
        </div>
    </div>
    <br>
    <textarea id="msg_box" rows="6" cols="50" onkeydown="confirm(event)"></textarea><br>
    <input type="button" value="發(fā)送" onclick="send()">
</div>
</body>
</html>
<script type="text/javascript">
    var uname = prompt('請輸入用戶名', 'user' + uuid(8, 16));
    var ws = new WebSocket("ws://127.0.0.1:8080/ws");
    ws.onopen = function () {
        var data = "系統(tǒng)消息:建立連接成功";
        listMsg(data);
    };
    ws.onmessage = function (e) {
        var msg = JSON.parse(e.data);
        var sender, user_name, name_list, change_type;
        switch (msg.type) {
            case 'system':
                sender = '系統(tǒng)消息: ';
                break;
            case 'user':
                sender = msg.from + ': ';
                break;
            case 'handshake':
                var user_info = {'type': 'login', 'content': uname};
                sendMsg(user_info);
                return;
            case 'login':
            case 'logout':
                user_name = msg.content;
                name_list = msg.user_list;
                change_type = msg.type;
                dealUser(user_name, change_type, name_list);
                return;
        }
        var data = sender + msg.content;
        listMsg(data);
    };
    ws.onerror = function () {
        var data = "系統(tǒng)消息 : 出錯(cuò)了,請退出重試.";
        listMsg(data);
    };
    function confirm(event) {
        var key_num = event.keyCode;
        if (13 == key_num) {
            send();
        } else {
            return false;
        }
    }
    function send() {
        var msg_box = document.getElementById("msg_box");
        var content = msg_box.value;
        var reg = new RegExp("\r\n", "g");
        content = content.replace(reg, "");
        var msg = {'content': content.trim(), 'type': 'user'};
        sendMsg(msg);
        msg_box.value = '';
    }
    function listMsg(data) {
        var msg_list = document.getElementById("msg_list");
        var msg = document.createElement("p");
        msg.innerHTML = data;
        msg_list.appendChild(msg);
        msg_list.scrollTop = msg_list.scrollHeight;
    }
    function dealUser(user_name, type, name_list) {
        var user_list = document.getElementById("user_list");
        var user_num = document.getElementById("user_num");
        while(user_list.hasChildNodes()) {
            user_list.removeChild(user_list.firstChild);
        }
        for (var index in name_list) {
            var user = document.createElement("p");
            user.innerHTML = name_list[index];
            user_list.appendChild(user);
        }
        user_num.innerHTML = name_list.length;
        user_list.scrollTop = user_list.scrollHeight;
        var change = type == 'login' ? '上線' : '下線';
        var data = '系統(tǒng)消息: ' + user_name + ' 已' + change;
        listMsg(data);
    }
    function sendMsg(msg) {
        var data = JSON.stringify(msg);
        ws.send(data);
    }
    function uuid(len, radix) {
        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        var uuid = [], i;
        radix = radix || chars.length;
        if (len) {
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
        } else {
            var r;
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }
        return uuid.join('');
    }
</script>

到了這里,關(guān)于Go語言網(wǎng)絡(luò)編程(socket編程)WebSocket編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • GO語言網(wǎng)絡(luò)編程(并發(fā)編程)Channel

    GO語言網(wǎng)絡(luò)編程(并發(fā)編程)Channel

    1.1.1 Channel 單純地將函數(shù)并發(fā)執(zhí)行是沒有意義的。函數(shù)與函數(shù)間需要交換數(shù)據(jù)才能體現(xiàn)并發(fā)執(zhí)行函數(shù)的意義。 雖然可以使用共享內(nèi)存進(jìn)行數(shù)據(jù)交換,但是共享內(nèi)存在不同的goroutine中容易發(fā)生競態(tài)問題。為了保證數(shù)據(jù)交換的正確性,必須使用互斥量對內(nèi)存進(jìn)行加鎖,這種做法勢

    2024年02月09日
    瀏覽(104)
  • GO語言網(wǎng)絡(luò)編程(并發(fā)編程)select

    1.1.1 select多路復(fù)用 在某些場景下我們需要同時(shí)從多個(gè)通道接收數(shù)據(jù)。通道在接收數(shù)據(jù)時(shí),如果沒有數(shù)據(jù)可以接收將會(huì)發(fā)生阻塞。你也許會(huì)寫出如下代碼使用遍歷的方式來實(shí)現(xiàn): 這種方式雖然可以實(shí)現(xiàn)從多個(gè)通道接收值的需求,但是運(yùn)行性能會(huì)差很多。為了應(yīng)對這種場景,G

    2024年02月09日
    瀏覽(239)
  • GO語言網(wǎng)絡(luò)編程(并發(fā)編程)runtime包

    1.1.1. runtime.Gosched() 讓出CPU時(shí)間片,重新等待安排任務(wù)(大概意思就是本來計(jì)劃的好好的周末出去燒烤,但是你媽讓你去相親,兩種情況第一就是你相親速度非???,見面就黃不耽誤你繼續(xù)燒烤,第二種情況就是你相親速度特別慢,見面就是你儂我儂的,耽誤了燒烤,但是還饞就

    2024年02月09日
    瀏覽(122)
  • GO語言網(wǎng)絡(luò)編程(并發(fā)編程)并發(fā)介紹,Goroutine

    GO語言網(wǎng)絡(luò)編程(并發(fā)編程)并發(fā)介紹,Goroutine

    進(jìn)程和線程 并發(fā)和并行 協(xié)程和線程 協(xié)程:獨(dú)立的??臻g,共享堆空間,調(diào)度由用戶自己控制,本質(zhì)上有點(diǎn)類似于用戶級(jí)線程,這些用戶級(jí)線程的調(diào)度也是自己實(shí)現(xiàn)的。 線程:一個(gè)線程上可以跑多個(gè)協(xié)程,協(xié)程是輕量級(jí)的線程。 goroutine 只是由官方實(shí)現(xiàn)的超級(jí)\\\"線程池\\\"。 每個(gè)

    2024年02月09日
    瀏覽(91)
  • Go語言網(wǎng)絡(luò)編程介紹以及案例運(yùn)用

    1. 基本概念 TCP 和 UDP : Go語言支持TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議)。TCP提供可靠的、面向連接的通信,而UDP提供無連接的快速數(shù)據(jù)傳輸。 并發(fā) : Go語言的并發(fā)模型是通過goroutines實(shí)現(xiàn)的。每個(gè)網(wǎng)絡(luò)請求都可以在自己的goroutine中處理,實(shí)現(xiàn)高效的并發(fā)。 Channels : 用于

    2024年01月25日
    瀏覽(105)
  • Go語言的網(wǎng)絡(luò)編程與HTTP服務(wù)

    Go語言(Golang)是Google開發(fā)的一種靜態(tài)類型、垃圾回收、并發(fā)簡單的編程語言。Go語言的設(shè)計(jì)目標(biāo)是讓程序員更容易編寫并發(fā)程序,并在多核處理器上充分發(fā)揮性能。Go語言的網(wǎng)絡(luò)編程和HTTP服務(wù)是其核心功能之一,可以輕松地構(gòu)建高性能、可擴(kuò)展的網(wǎng)絡(luò)應(yīng)用程序。 在本文中,我們

    2024年02月19日
    瀏覽(99)
  • Go語言實(shí)戰(zhàn):網(wǎng)絡(luò)編程與TCP_UDP

    Go語言是一種現(xiàn)代的編程語言,由Google的Robert Griesemer、Rob Pike和Ken Thompson于2009年開發(fā)。Go語言的設(shè)計(jì)目標(biāo)是簡單、高效、可擴(kuò)展和易于使用。它具有垃圾回收、類型安全、并發(fā)性能等優(yōu)點(diǎn)。Go語言的網(wǎng)絡(luò)編程庫 net 包提供了TCP/UDP的實(shí)現(xiàn),使得開發(fā)者可以輕松地編寫網(wǎng)絡(luò)應(yīng)用程序

    2024年02月21日
    瀏覽(96)
  • Go語言的網(wǎng)絡(luò)編程與TCP_IP

    Go語言是一種現(xiàn)代的編程語言,由Google的Robert Griesemer、Rob Pike和Ken Thompson在2009年開發(fā)。Go語言的設(shè)計(jì)目標(biāo)是簡單、高效、可擴(kuò)展和易于使用。它具有弱類型、垃圾回收、并發(fā)性和原生支持的網(wǎng)絡(luò)編程。Go語言的網(wǎng)絡(luò)編程是其強(qiáng)大功能之一,它使得開發(fā)者可以輕松地編寫高性能的

    2024年02月22日
    瀏覽(115)
  • Java網(wǎng)絡(luò)Socket編程-websocket

    實(shí)現(xiàn)一個(gè)用于監(jiān)測 WebSocket 連接狀態(tài)的線程類,其作用是通過創(chuàng)建一個(gè) WebSocket 客戶端,連接到指定的 WebSocket 地址,并監(jiān)測連接的狀態(tài)。 代碼中的 WebSocketThread 類繼承自 Thread ,意味著它可以在單獨(dú)的線程中執(zhí)行。該線程類使用 Tyrus 提供的 @ClientEndpoint 注解來標(biāo)識(shí)這是一個(gè)

    2024年02月08日
    瀏覽(21)
  • golang網(wǎng)絡(luò)編程學(xué)習(xí)-websocket

    golang網(wǎng)絡(luò)編程學(xué)習(xí)-websocket

    golang網(wǎng)絡(luò)編程學(xué)習(xí)-websocket 網(wǎng)絡(luò)編程主要的內(nèi)容是: 1.TCP網(wǎng)絡(luò)編程 2.http服務(wù) 3.rpc服務(wù) 4.websocket服務(wù) 1.1服務(wù)端,代碼來自網(wǎng)絡(luò),僅限于學(xué)習(xí)研究 ? 服務(wù)端截圖 ? 1.2客戶端,代碼來自網(wǎng)絡(luò),僅限于學(xué)習(xí)研究 ? ? ?客戶端瀏覽器運(yùn)行內(nèi)容信息 ? ?

    2024年02月17日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包