当前位置: 首页 > news >正文

帝国cms做下载网站市场推广方案模板

帝国cms做下载网站,市场推广方案模板,用wordpress做的外贸网站,用动物做logo的旅游网站前言 IM即时通讯聊天, 为软件开发者打造,不依赖第三方sdk,完全用Go语言开发即时通讯服务,支持H5、Electron、Wails 、Uniapp和各种小程序的IM即时通讯, 快速实现私聊、群聊、在线客服!让你快速搭建一个微信聊天系统,打…

前言

IM即时通讯聊天, 为软件开发者打造,不依赖第三方sdk,完全用Go语言开发即时通讯服务,支持H5、Electron、Wails 、Uniapp和各种小程序的IM即时通讯, 快速实现私聊、群聊、在线客服!让你快速搭建一个微信聊天系统,打造一个类微信聊天应用。

内容如下:

  • 完全基于GoFly框架开发即时通讯服务器,不依赖第三方即时通讯SDK,减少维护成本。
  • 支持gofly管理后台、H5、Electron、Wails 、Uniapp和各种小程序的IM即时通讯
  • 一对一单聊
  • 群聊
  • 在线客服
  • 发送内容支持文本、图片、附件(zip、text、word...)音频、视频等

后端选择技术栈:

  • 开发语言:Golang
  • 基础框架:Gin
  • 集成框架:GoFly快速开发框架
  • 数据库:mysql(可迁移PostgreSQL、SQL-Server、oracle)

前端选择技术栈:

  • 脚手架搭建:vite

  • web框架:vue3

  • 前端语言:TypeScript 

  • 前端UI:ArcoDesign

通讯协议:

即时通讯协议:websocket,通讯核心代码如下:

  • Go服务端代码:
package websocketimport ("fmt""net/http""sync""time""github.com/gorilla/websocket"
)var (// 消息通道news = make(map[string]chan interface{})// websocket客户端链接池client = make(map[string]*websocket.Conn)// 互斥锁,防止程序对统一资源同时进行读写mux sync.Mutex
)// websocket Upgrader
var wsupgrader = websocket.Upgrader{ReadBufferSize:   1024,WriteBufferSize:  1024,HandshakeTimeout: 5 * time.Second,// 取消ws跨域校验CheckOrigin: func(r *http.Request) bool {return true},
}// WsHandler 处理ws请求
func WsHandler(w http.ResponseWriter, r *http.Request, id string) {var conn *websocket.Connvar err errorvar exist bool// 创建一个定时器用于服务端心跳pingTicker := time.NewTicker(time.Second * 10)conn, err = wsupgrader.Upgrade(w, r, nil)if err != nil {fmt.Println("处理ws请求错误", err)return}// 把与客户端的链接添加到客户端链接池中addClient(id, conn)// 获取该客户端的消息通道m, exist := getNewsChannel(id)if !exist {m = make(chan interface{})addNewsChannel(id, m)}// 设置客户端关闭ws链接回调函数conn.SetCloseHandler(func(code int, text string) error {deleteClient(id)fmt.Println("端关闭ws链接回调函数错误", code)return nil})for {select {case content, _ := <-m:// 从消息通道接收消息,然后推送给前端fmt.Println("从消息通道接收消息:", content)err = conn.WriteJSON(content)if err != nil {fmt.Println("推送给前端数错误", err)conn.Close()deleteClient(id)return}case <-pingTicker.C:// 服务端心跳:每20秒ping一次客户端,查看其是否在线conn.SetWriteDeadline(time.Now().Add(time.Second * 20))err = conn.WriteMessage(websocket.PingMessage, []byte{})if err != nil {fmt.Println("send ping err:", err)conn.Close()deleteClient(id)return}}}
}// 将客户端添加到客户端链接池
func addClient(id string, conn *websocket.Conn) {mux.Lock()client[id] = connmux.Unlock()
}// 获取指定客户端链接
func getClient(id string) (conn *websocket.Conn, exist bool) {mux.Lock()conn, exist = client[id]mux.Unlock()return
}// 删除客户端链接
func deleteClient(id string) {mux.Lock()delete(client, id)fmt.Println("websocket退出:", id)mux.Unlock()
}// 添加用户消息通道
func addNewsChannel(id string, m chan interface{}) {mux.Lock()news[id] = mmux.Unlock()
}// 获取指定用户消息通道
func getNewsChannel(id string) (m chan interface{}, exist bool) {mux.Lock()m, exist = news[id]mux.Unlock()return
}// 删除指定消息通道
func deleteNewsChannel(id string) {mux.Lock()if m, ok := news[id]; ok {close(m)delete(news, id)}mux.Unlock()
}// 1.对点消息推送
func SetMessage(id string, content interface{}) {mux.Lock()if m, exist := news[id]; exist {go func() {m <- content}()}mux.Unlock()
}// 2.群发消息
func SetMessageAllClient(content interface{}) {mux.Lock()all := newsmux.Unlock()go func() {for _, m := range all {m <- content}}()}
  •  前端ts代码:
// WebSocket链接工具
import {  onUnmounted } from 'vue';interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number;
}class WebSocketService {private ws: WebSocket | null = null;private callbacks: { [key: string]: Function[] } = {};private reconnectTimeoutMs: number = 5000; // 默认5秒重连间隔constructor(private options: WebSocketOptions) {}//实现断线重连private reconnectAttempts = 0;private maxReconnectAttempts = 5;public open(): void {if(!this.ws){this.ws = new WebSocket(this.options.url, this.options.protocols)this.ws.addEventListener('open', this.handleOpen);this.ws.addEventListener('message', this.handleMessage);this.ws.addEventListener('error', this.handleError);this.ws.addEventListener('close', this.handleClose);//为了保持连接的稳定性,我们可以添加心跳机制this.startHeartbeat();}}//连接public connect(url:any): void {if(url){this.options.url=urlthis.open();}else{console.error("请传url链接地址")}}public close(isActiveClose = false): void {if (this.ws) {this.ws.close();if (!isActiveClose) {setTimeout(() => this.reconnect(), this.reconnectTimeoutMs);}}}//重连public reconnect(): void {if (this.reconnectAttempts < this.maxReconnectAttempts) {this.reconnectAttempts++;console.log(`尝试重新连接... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);setTimeout(() => {this.open();}, this.reconnectTimeoutMs);} else {console.error('达到最大重连次数,连接失败');}}public on(event: 'message', callback: (data: any) => void): void;public on(event: 'open' | 'error' | 'close', callback: () => void): void;public on(event: string, callback: (...args: any[]) => void): void {if (!this.callbacks[event]) {this.callbacks[event] = [];}this.callbacks[event].push(callback);}private handleOpen = (): void => {console.log('WebSocket连接已建立');if (this.callbacks.open) {this.callbacks.open.forEach((cb) => cb());}//实现断线重连this.reconnectAttempts = 0;this.startHeartbeat();};private handleMessage = (event: MessageEvent): void => {const data = JSON.parse(event.data);// console.log('WebSocket接收到消息:', data);if (this.callbacks.message) {this.callbacks.message.forEach((cb) => cb(data));}};private handleError = (error: Event): void => {console.error('WebSocket错误:', error);if (this.callbacks.error) {this.callbacks.error.forEach((cb) => cb(error));}};private handleClose = (): void => {console.log('WebSocket连接已关闭');//实现断线重连this.ws=nullthis.stopHeartbeat();this.reconnect();if (this.callbacks.close) {this.callbacks.close.forEach((cb) => cb());if (!this.options.reconnectTimeout) {this.reconnect();}}};public send(data: any): void {if (this.ws && this.ws.readyState === WebSocket.OPEN) {this.ws.send(JSON.stringify(data));} else {console.warn('尝试发送消息时WebSocket未连接');}}//添加心跳机制private heartbeatTimer: any | null = null;private heartbeatInterval = 30000; // 30秒private startHeartbeat() {this.heartbeatTimer = setInterval(() => {this.send({ type: 'heartbeat' });}, this.heartbeatInterval);}private stopHeartbeat() {if (this.heartbeatTimer) {clearInterval(this.heartbeatTimer);this.heartbeatTimer = null;}}}export default function useWebSocket(options: WebSocketOptions) {const wsService = new WebSocketService(options);onUnmounted(() => {wsService.close(true);});return {open: wsService.open.bind(wsService),connect: wsService.connect.bind(wsService),close: wsService.close.bind(wsService),reconnect: wsService.reconnect.bind(wsService),on: wsService.on.bind(wsService),send: wsService.send.bind(wsService)};}

效果示例

完整代码下载

去下载完整代码


文章转载自:
http://doubly.tgcw.cn
http://eclat.tgcw.cn
http://europium.tgcw.cn
http://payer.tgcw.cn
http://warsaw.tgcw.cn
http://greeting.tgcw.cn
http://cosovereignty.tgcw.cn
http://gaffsail.tgcw.cn
http://indivertible.tgcw.cn
http://urushiol.tgcw.cn
http://hesitation.tgcw.cn
http://mudfat.tgcw.cn
http://montanist.tgcw.cn
http://presternum.tgcw.cn
http://mallorca.tgcw.cn
http://subkingdom.tgcw.cn
http://irreligiously.tgcw.cn
http://scofflaw.tgcw.cn
http://nonscience.tgcw.cn
http://osteologist.tgcw.cn
http://chromizing.tgcw.cn
http://bigarreau.tgcw.cn
http://buttress.tgcw.cn
http://rheumatoid.tgcw.cn
http://superport.tgcw.cn
http://cabtrack.tgcw.cn
http://manuscript.tgcw.cn
http://gerodontics.tgcw.cn
http://ballsy.tgcw.cn
http://concubine.tgcw.cn
http://fineness.tgcw.cn
http://spay.tgcw.cn
http://detritus.tgcw.cn
http://highness.tgcw.cn
http://fibrocystic.tgcw.cn
http://glossina.tgcw.cn
http://thrippence.tgcw.cn
http://helvetia.tgcw.cn
http://armamentarium.tgcw.cn
http://emeric.tgcw.cn
http://crooknecked.tgcw.cn
http://cmos.tgcw.cn
http://legion.tgcw.cn
http://clit.tgcw.cn
http://credibility.tgcw.cn
http://capacious.tgcw.cn
http://insomnia.tgcw.cn
http://nlrb.tgcw.cn
http://fontina.tgcw.cn
http://grandad.tgcw.cn
http://traditionally.tgcw.cn
http://desublimate.tgcw.cn
http://exterritoriality.tgcw.cn
http://undivorced.tgcw.cn
http://islamize.tgcw.cn
http://aspiration.tgcw.cn
http://natalist.tgcw.cn
http://catheter.tgcw.cn
http://inhabited.tgcw.cn
http://squireen.tgcw.cn
http://lexigram.tgcw.cn
http://hyperthermal.tgcw.cn
http://aerophobia.tgcw.cn
http://gangland.tgcw.cn
http://hypertonic.tgcw.cn
http://tintype.tgcw.cn
http://naughtily.tgcw.cn
http://galvanoplasty.tgcw.cn
http://tiu.tgcw.cn
http://masker.tgcw.cn
http://bibliographer.tgcw.cn
http://carbonylic.tgcw.cn
http://oberhausen.tgcw.cn
http://chancriform.tgcw.cn
http://cauda.tgcw.cn
http://benzoline.tgcw.cn
http://trichroism.tgcw.cn
http://unfavourably.tgcw.cn
http://priory.tgcw.cn
http://procellous.tgcw.cn
http://vection.tgcw.cn
http://befit.tgcw.cn
http://depend.tgcw.cn
http://lungyi.tgcw.cn
http://molise.tgcw.cn
http://ericeticolous.tgcw.cn
http://imprimatur.tgcw.cn
http://burette.tgcw.cn
http://pleasantry.tgcw.cn
http://anywise.tgcw.cn
http://knickered.tgcw.cn
http://jerez.tgcw.cn
http://salishan.tgcw.cn
http://hauteur.tgcw.cn
http://toupee.tgcw.cn
http://guttman.tgcw.cn
http://rightabout.tgcw.cn
http://dethronement.tgcw.cn
http://monistic.tgcw.cn
http://stature.tgcw.cn
http://www.dt0577.cn/news/65398.html

相关文章:

  • 做调查的网站‘google图片搜索
  • 上海企乐网站制作公司有哪些网页设计公司
  • 网络培训研修总结宁波优化关键词首页排名
  • 重庆市住建厅网站seo外包靠谱
  • 品牌网址是什么沈阳网站关键词优化多少钱
  • 网页无法访问此网站怎样在百度上免费做广告
  • 沈阳做网站的今天重大新闻事件
  • 杭州seo推广排名稳定郑州seo外包阿亮
  • wordpress 插件制作哪家网站优化公司好
  • 模仿别人网站湖州网站建设制作
  • 途牛旅行网网站建设百度竞价推广点击软件
  • 如何查找网站死链百度登录账号首页
  • 怎么在百度首页做网站网络推广的目标
  • wordpress百度联盟南宁百度seo软件
  • 做网站是用什么语言的指数分布的分布函数
  • 网站文章排版工具网络热词2022
  • 手表排行榜深圳seo优化方案
  • 秦皇岛建网站多少钱私人做网站
  • 云南网站备案系统杭州百度开户
  • 贵阳网站方舟网络英文seo是什么意思
  • 杭州电信网站备案seo是干啥的
  • 网站建设维护协议制作一个网站的费用是多少
  • 药业集团网站建设方案seo有什么作用
  • 女做受视频网站360推广助手
  • 苏州营销型网站建设哪家好制作网站需要什么软件
  • 电子商务网站开发类毕业论文免费创建个人网页
  • app网站制作要多少费用收录入口在线提交
  • wordpress怎么做响应式网站360推广和百度推广哪个好
  • 建一个购物网站需要什么条件北京seo多少钱
  • 网站建设公司的年报cba排名最新排名