golang网络编程学习-websocket

news2024/11/25 16:52:30

golang网络编程学习-websocket

网络编程主要的内容是:
1.TCP网络编程
2.http服务
3.rpc服务
4.websocket服务

 一、websocket编程

1.1服务端,代码来自网络,仅限于学习研究

package main

import (
	"fmt"
	"net/http"
	"os"
	"reflect"
	"time"
	"unsafe"

	"github.com/gorilla/websocket"
)

type HttpHandler struct {
	http.Handler
}

func main() {
	var httpHandler HttpHandler
	http.Handle("/connect", httpHandler)
	if err := http.ListenAndServe(":9999", nil); err != nil {
		fmt.Println("程序退出")
		os.Exit(1)
	}
}

func (httpHandler HttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Println("程序进入监听>>")
	var upgrader = websocket.Upgrader{
		//解决跨域问题
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("upgrade error:", err)
		return
	}
	defer conn.Close()
	conn.SetReadDeadline(time.Now().Add(6 * time.Second))
	conn.SetPongHandler(func(string) error {
		fmt.Println("接收心跳响应<<")
		conn.SetReadDeadline(time.Now().Add(6 * time.Second))
		return nil
	})
	ticker := time.NewTicker(2 * time.Second)
	go func() {
		for {
			//从定时器中获取数据
			_ = <-ticker.C
			fmt.Println("发送心跳包>>")
			conn.WriteMessage(websocket.PingMessage, []byte{})
		}
	}()
	defer ticker.Stop()
	for {
		messageType, message, err := conn.ReadMessage()
		if err != nil {
			fmt.Println("接收异常:", err)
			break
		}
		fmt.Println(fmt.Sprintf("接收消息内容 >>%s", message))
		respMessage := fmt.Sprintf("I am Server, %s.", time.Now().Format("2006-01-02 15:04:05"))
		err = conn.WriteMessage(messageType, String2Bytes(respMessage))
		if err != nil {
			fmt.Println("发送异常:", err)
			break
		}
	}
}

func String2Bytes(s string) []byte {
	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
	bh := reflect.SliceHeader{
		Data: sh.Data,
		Len:  sh.Len,
		Cap:  sh.Len,
	}
	return *(*[]byte)(unsafe.Pointer(&bh))
}

 

服务端截图

 

1.2客户端,代码来自网络,仅限于学习研究

<html>
<head>
    <meta charset="UTF-8"/>
</head>
<body>
<div>
    <button onclick="start()" style="width:80px;height:30px;line-height:24px;">开始</button>
    <button onclick="stop()" style="width:80px;height:30px;line-height:24px;">停止</button>
    <button onclick="reset()" style="width:80px;height:30px;line-height:24px;">重置</button>
</div>
<div id="connect-show">未连接</div>
<div id="rec-show"></div>
</body>
<script type="text/javascript">
    var ws;
    var interval;

    function rewebsocket() {
        //ws = new WebSocket("ws://127.0.0.1:9999/connect");
        ws = new WebSocket("ws://127.0.0.1:9999/connect");
        //连接建立时触发
        ws.onopen = function() {
            document.getElementById("connect-show").innerHTML = "连接成功";
            send(ws);
        }
        //连接关闭时触发
        ws.onclose = function() {
            document.getElementById("connect-show").innerHTML = "连接已关闭";
        }
        //通信发生错误时触发
        ws.onerror = function() {
            document.getElementById("connect-show").innerHTML = "连接通讯成功";
        }
        //客户端接收服务端数据时触发
        ws.onmessage = function(e) {
            var recMsg = e.data;
            var element = document.getElementById("rec-show");
            var nodes = element.childNodes;
            if (nodes && nodes.length >= 20) {
                element.removeChild(nodes[nodes.length-1])
            }
            element.innerHTML = ("<div>" + recMsg + "</div>" + element.innerHTML);
        }
    }

    //启动
    function start() {
        if (ws == undefined || ws.readyState >= 2) {
            rewebsocket();
        }
    }

    //停止
    function stop() {
        clearInterval(interval);
        closeWebsocket(ws);
        interval = undefined;
        ws = undefined;
    }

    //重置
    function reset() {
        stop();
        document.getElementById("connect-show").innerHTML = "未连接";
        document.getElementById("rec-show").innerHTML = "";
        start();
    }

    //消息发送策略
    function send(ws) {
        interval = setInterval(() => {
            ws.send("I am client, " + getTime() + ".")
        },1000);
    }

    //获取客户端年月日时分秒
    function getTime() {
        return new Date( +new Date() + 8 * 3600 * 1000 ).toJSON().substr(0,19).replace("T"," ");
    }

    //关闭websocket连接
    function closeWebsocket(ws) {
        try {
            if (ws != undefined && ws.readyState < 2) {
                ws.close();
            }
        } catch (err){}
    }
</script>
</html>

 

 

 客户端浏览器运行内容信息

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧签 - 开源研究系列文章

这些天整理了一下以前的代码&#xff0c;将一个插件里的便签器的源码单独找出来&#xff0c;弄成了这个“智慧签”的程序。程序比较简单&#xff0c;具体请读者自己看代码。 1、 项目目录&#xff1b; 目录见下图&#xff0c;对代码进行了划分&#xff0c;比较简单。主处…

golang网络编程学习-1rpc

网络编程主要的内容是&#xff1a; 1.TCP网络编程 2.http服务 3.rpc服务 4.websocket服务 一、rpc RPC 框架----- 远程过程调用协议RPC&#xff08;Remote Procedure Call Protocol)-----允许像调用本地服务一样调用远程服务。 RPC是指远程过程调用&#xff0c;也就是说两台服…

visual studio配置调用c++ dll opencv为例

1&#xff0c;配置VC目录&#xff0c;包含目录和库目录。 2&#xff0c;链接器->输入->包含目录 3&#xff0c;生成目录下包含对应的dll文件 4&#xff0c;需注意对应的Debug&#xff0c;Release及X86&#xff0c;X64选项

flutter 自适应宽高气泡框,聊天气泡框

先看效果 前言&#xff1a;&#xff1a;&#xff1a;&#xff1a; 网上好多气泡框&#xff0c;都让写固定宽高&#xff0c;无法自适应文本内容。 还有的就是通过算child 然后动态计算气泡框宽高&#xff0c;脱裤子&#x1f4a8;&#xff0c;放到listview 刷新数据还会丢ui&am…

Spring Cloud Alibaba的组件(解决方案)

Spring Cloud Alibaba的组件&#xff08;解决方案&#xff09; 前言Spring CloudSpring Cloud Alibaba问题的解决方案面临的问题Spring Cloud Alibaba给出的解决方案 前言 在之前的文章里我们介绍了分布式微服务以及其需要解决的问题&#xff0c;现在我们看看在Spring Cloud A…

31. IO操作

一、概览二、磁盘操作三、字节操作 实现文件复制装饰者模式 四、字符操作 编码与解码String 的编码方式Reader 与 Writer实现逐行输出文本文件的内容 五、对象操作 序列化Serializabletransient 六、网络操作 InetAddressURLSocketsDatagram 七、NIO 流与块通道与缓冲区缓冲区状…

数据结构基本概念、线性表、顺序表

一、头文件 head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXSIZE 8typedef int datatype; typedef struct {int len;datatype data[MAXSIZE]; }Seqlist;Seqlist * Request_space(voi…

利用python绘制对数坐标轴

利用python绘制对数坐标轴 1&#xff09;效果图 2&#xff09; 程序代码 import matplotlib.pyplot as plt import numpy as np# 设置图形的大小 plt.figure(figsize(8, 6))# 设置x轴的范围为10的-4次方到10的3次方 plt.xlim(1e-4, 1e3)# 绘制x轴的对数坐标轴 plt.xscale(log…

浅谈防火门监控系统在酒店防火安全中的重要应用

安科瑞 华楠 摘要&#xff1a;建筑防火问题已经引起人们的广泛关注&#xff0c;合理进行建筑消防设计成为了建筑设计的重要内容。防火门监控系统是建筑防火研究的新成果。对日常防火分区监控及发生火灾后对火势和有毒气体的控制起到关建作用。文章对防火门监控系统的组成和工…

网络安全(黑客技术)自学笔记+就业市场前景分析

一、针对网络安全市场分析 市场需求量高&#xff1b;则是发展相对成熟入门比较容易。所需要的技术水平国家政策环境 对于国家与企业的地位愈发重要&#xff0c;没有网络安全就没有国家安全 更有为国效力的正义黑客—红客联盟 可见其重视程度。 需要掌握的知识点偏多 外围打点…

18 - 堆栈 - 二项堆

前面我们学习了斐波那契堆, 今天我们来学习二项堆! 二项堆 二项堆是二项树的集合或是由一组二项树组成。 二项堆H由一组满足以下性质的二项树组成: 1) H中的每个二项树都遵循最小堆性质:节点的关键字不大于其子节点的关键字。因此,根的关键字最小 2) 对任意非负整数…

【ARM——当前程序状态寄存器 CPSR

文章目录 CPSRSPSRSPSRCPSR 各个位含义 CPSR Current Program Status Register 即 CPSR,当前程序状态寄存器&#xff0c;可以在任何处理器模式下被访问。它包含了条件标志位、中断禁止位&#xff0c;当前处理器模式标志以及其他的一些控制和状态位。 SPSR 除了 usr 和 sys 模…

【C++】list的使用及底层实现原理

本篇文章对list的使用进行了举例讲解。同时也对底层实现进行了讲解。底层的实现关键在于迭代器的实现。希望本篇文章会对你有所帮助。 文章目录 一、list的使用 1、1 list的介绍 1、2 list的使用 1、2、1 list的常规使用 1、2、2 list的sort讲解 二、list的底层实现 2、1 初构…

vue文件上传,文件打不开。文件上传 on-progress不触发

//文件上传带进度条<el-uploadv-model:file-list"fileList":limit"3":on-progress"beforeAvatarUpload"//on-progress 不触发&#xff0c;触发的关键在于覆盖原有的http请求:http-request"getFile":action"${app.api}/student…

【从零开始学习JAVA | 第二十九篇】Stream流

目录 前言&#xff1a; Stram流&#xff1a; 设计目标&#xff1a; 使用步骤&#xff1a; 1.先得到一条Stream流&#xff0c;并把数据放上去。 2.利用Stream流中的各种API进行操作。 使用Stream流的注意事项&#xff1a; 总结: 前言&#xff1a; 本文我们将学习Stream流…

Windows用户注意!LokiBot恶意软件正通过Office文档传播

Windows用户再次成为被称为LokiBot恶意软件的攻击目标&#xff0c;该恶意软件通过Office文档进行传播。 根据Fortinet安全研究员Cara Lin的最新报告&#xff0c;攻击者利用已知漏洞&#xff0c;如CVE-2021-40444和CVE-2022-30190&#xff0c;在微软Office文档中嵌入恶意宏。 …

Eulaceura 版本 23H1:RISC-V 架构新的里程碑

近日&#xff0c;RISC-V SIG 发布了 Eulaceura 版本 23H1&#xff0c;这是发行版的一次重大更新&#xff0c;新版本搭建了 linux kernel 6.1 版本内核&#xff0c;适用于矽速科技 LicheePi 4A 的映像也已公布。Eulaceura 是首个将 RISC-V 架构纳入第一级支持范围的 openEuler 发…

深入理解网络栈

网络路径 发送端 应用层 1、socket 各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的 socket 是网络编程的入口&#xff0c;它提供了大量的系统调用&#xff0c;构成了网络程序的主体 udp UDP 是面向无连接的协议&#xff0c;不需要与…

CycleGAN论文的阅读与翻译,无监督风格迁移、对抗损失

CycleGAN论文的阅读与翻译&#xff0c;无监督风格迁移 CycleGAN 论文原文 arXiv CycleGAN junyanz&#xff0c;作者自己用 lua 在 GitHub 上的实现 CycleGAN tensorflow PyTorch by LynnHo&#xff0c;一个简单的 TensorFlow 实现 0. 摘要&#xff1a; 图像到图像的翻译 (Ima…

黑马大数据学习笔记2-HDFS基本操作

目录 进程启停管理一键启停脚本单进程启停 文件系统操作命令HDFS文件系统基本信息介绍创建文件夹查看指定目录下内容上传文件到HDFS指定目录查看HDFS文件内容下载HDFS文件拷贝HDFS文件追加数据到HDFS文件HDFS数据移动HDFS数据删除其他命令HDFS WEB浏览 HDFS权限修改权限 https:…