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

有哪些网站做的好iis网站批量导入

有哪些网站做的好,iis网站批量导入,做网站需要的流程,电商平台网站有哪些WebSocket编程 WebSocket协议解读 websocket和http协议的关联: 都是应用层协议,都基于tcp传输协议。跟http有良好的兼容性,ws和http的默认端口都是80,wss和https的默认端口都是443。websocket在握手阶段采用http发送数据。 we…

WebSocket编程

WebSocket协议解读

websocket和http协议的关联:

  • 都是应用层协议,都基于tcp传输协议。
  • 跟http有良好的兼容性,ws和http的默认端口都是80,wss和https的默认端口都是443。
  • websocket在握手阶段采用http发送数据。

websocket和http协议的差异:

  • http是半双工,而websocket通过多路复用实现了全双工。
  • http只能由client主动发起数据请求,而websocket还可以由server主动向client推送数据。在需要及时刷新的场景中,http只能靠client高频地轮询,浪费严重。
  • http是短连接(也可以实现长连接, HTTP1.1 的连接默认使用长连接),每次数据请求都得经过三次握手重新建立连接,而websocket是长连接。
  • http长连接中每次请求都要带上header,而websocket在传输数据阶段不需要带header。

  WebSocket是HTML5下的产物,能更好的节省服务器资源和带宽,websocket应用场景举例:

  • html5多人游戏
  • 聊天室
  • 协同编辑
  • 基于实时位置的应用
  • 股票实时报价
  • 弹幕
  • 视频会议

websocket握手协议:
Request Header

Sec-Websocket-Version:13
Upgrade:websocket
Connection:Upgrade
Sec-Websocket-Key:duR0pUQxNgBJsRQKj2Jxsw==

Response Header

Upgrade:websocket
Connection:Upgrade
Sec-Websocket-Accept:a1y2oy1zvgHsVyHMx+hZ1AYrEHI=
  • Upgrade:websocket和Connection:Upgrade指明使用WebSocket协议。
  • Sec-WebSocket-Version 指定Websocket协议版本。
  • Sec-WebSocket-Key是一个Base64 encode的值,是浏览器随机生成的。
  • 服务端收到Sec-WebSocket-Key后拼接上一个固定的GUID,进行一次SHA-1摘要,再转成Base64编码,得到Sec-WebSocket-Accept返回给客户端。客户端对本地的Sec-WebSocket-Key执行同样的操作跟服务端返回的结果进行对比,如果不一致会返回错误关闭连接。如此操作是为了把websocket header跟http header区分开。

WebSocket CS架构实现

  首先需要安装gorilla的websocket包。

go get github.com/gorilla/websocket
  1. 将http升级到WebSocket协议。
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*websocket.Conn, error)
  1. 客户端发起握手,请求建立连接。
func (*websocket.Dialer) Dial(urlStr string, requestHeader http.Header) (*websocket.Conn, *http.Response, error)
  1. 基于connection进行read和write。

ws_server.go

package mainimport ("fmt""go-course/socket""net""net/http""strconv""time""github.com/gorilla/websocket"
)type WsServer struct {listener net.Listeneraddr     stringupgrade  *websocket.Upgrader
}func NewWsServer(port int) *WsServer {ws := new(WsServer)ws.addr = "0.0.0.0:" + strconv.Itoa(port)ws.upgrade = &websocket.Upgrader{HandshakeTimeout: 5 * time.Second, //握手超时时间ReadBufferSize:   2048,            //读缓冲大小WriteBufferSize:  1024,            //写缓冲大小//请求检查函数,用于统一的链接检查,以防止跨站点请求伪造。如果Origin请求头存在且原始主机不等于请求主机头,则返回falseCheckOrigin: func(r *http.Request) bool {fmt.Printf("request url %s\n", r.URL)fmt.Println("handshake request header")for key, values := range r.Header {fmt.Printf("%s:%s\n", key, values[0])}return true},//http错误响应函数Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {},}return ws
}//httpHandler必须实现ServeHTTP接口
func (ws *WsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {if r.URL.Path != "/add" {fmt.Println("path error")http.Error(w, "请求的路径不存在", 222) //把出错的话术写到ResponseWriter里return}conn, err := ws.upgrade.Upgrade(w, r, nil) //将http协议升级到websocket协议if err != nil {fmt.Printf("upgrade http to websocket error: %v\n", err)return}fmt.Printf("establish conection to client %s\n", conn.RemoteAddr().String())go ws.handleConnection(conn)
}//处理连接里发来的请求数据
func (ws *WsServer) handleConnection(conn *websocket.Conn) {defer func() {conn.Close()}()for { //长连接conn.SetReadDeadline(time.Now().Add(20 * time.Second))var request socket.Requestif err := conn.ReadJSON(&request); err != nil {//判断是不是超时if netError, ok := err.(net.Error); ok { //如果ok==true,说明类型断言成功if netError.Timeout() {fmt.Printf("read message timeout, remote %s\n", conn.RemoteAddr().String())return}}//忽略websocket.CloseGoingAway/websocket.CloseNormalClosure这2种closeErr,如果是其他closeErr就打一条错误日志if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseNormalClosure) {fmt.Printf("read message from %s error %v\n", conn.RemoteAddr().String(), err)}return //只要ReadMessage发生错误,就关闭这条连接} else {response := socket.Response{Sum: request.A + request.B}if err = conn.WriteJSON(&response); err != nil {fmt.Printf("write response failed: %v", err)} else {fmt.Printf("write response %d\n", response.Sum)}}}
}func (ws *WsServer) Start() (err error) {ws.listener, err = net.Listen("tcp", ws.addr) //http和websocket都是建立在tcp之上的if err != nil {fmt.Printf("listen error:%s\n", err)return}err = http.Serve(ws.listener, ws) //开始对外提供http服务。可以接收很多连接请求,其他一个连接处理出错了,也不会影响其他连接if err != nil {fmt.Printf("http server error: %v\n", err)return}// if err:=http.ListenAndServe(ws.addr, ws);err!=nil{	//Listen和Serve两步合成一步// 	fmt.Printf("http server error: %v\n", err)// 	return// }return nil
}func main() {ws := NewWsServer(5657)ws.Start()
}

ws_client.go

package mainimport ("encoding/json""fmt""go-course/socket""io/ioutil""net/http""time""github.com/gorilla/websocket"
)func main() {dialer := &websocket.Dialer{}header := http.Header{"Cookie": []string{"name=zcy"},}conn, resp, err := dialer.Dial("ws://localhost:5657/add", header) //Dial:握手阶段,会发送一条http请求。请求一个不存在的路径试试看defer resp.Body.Close()if err != nil {fmt.Printf("dial server error:%v\n", err)fmt.Println(resp.StatusCode)msg, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(msg))return}fmt.Println("handshake response header")for key, values := range resp.Header {fmt.Printf("%s:%s\n", key, values[0])}// time.Sleep(5 * time.Second)defer conn.Close()for i := 0; i < 10; i++ {request := socket.Request{A: 7, B: 4}requestBytes, _ := json.Marshal(request)err = conn.WriteJSON(request) //websocket.Conn直接提供发json序列化和反序列化方法socket.CheckError(err)fmt.Printf("write request %s\n", string(requestBytes))var response socket.Responseerr = conn.ReadJSON(&response)socket.CheckError(err)fmt.Printf("receive response: %d\n", response.Sum)time.Sleep(1 * time.Second)}time.Sleep(30 * time.Second)
}

  websocket发送的消息类型有5种:TextMessag,BinaryMessage, CloseMessag,PingMessage,PongMessage。TextMessag和BinaryMessage分别表示发送文本消息和二进制消息。CloseMessage关闭帧,接收方收到这个消息就关闭连接
PingMessage和PongMessage是保持心跳的帧,发送方接收方是PingMessage,接收方发送方是PongMessage,目前浏览器没有相关api发送ping给服务器,只能由服务器发ping给浏览器,浏览器返回pong消息。

聊于室实现

  gorilla的websocket项目中有一个聊天室的demo,此处讲一下它的设计思路。我们的代码基于原代码进行了简化和修改,并加上中文注释。总体架构如下图所示

Hub

  • Hub持有每一个Client的指针,broadcast管道里有数据时把它写入每一个Client的send管道中。
  • 注销Client时关闭Client的send管道。

Client

  • 前端(browser)请求建立websocket连接时,为这条websocket连接专门启一个协程,创建一个client。
  • client把前端发过来的数据写入hub的broadcast管道。
  • client把自身send管道里的数据写给前端。
  • client跟前端的连接断开时请求从hub那儿注销自己。

Front

  • 当打开浏览器页面时,前端会请求建立websocket连接。
  • 关闭浏览器页面时会主动关闭websocket连接。

存活监测

  • 当hub发现client的send管道写不进数据时,把client注销掉。
  • client给websocket连接设置一个读超时,并周期性地给前端发ping消息,如果没有收到pong消息则下一次的conn.read()会报出超时错误,此时client关闭websocket连接。
http://www.yayakq.cn/news/402968/

相关文章:

  • 网页制作与网站制作违规网站备案
  • 十大高端网站定制设计师找人帮忙注册app推广
  • 网站建设与设计教程视频湖南平台网站建设制作
  • 西安专业的网站设计费用社旗微网站开发
  • 海南房产网站开发做外贸网站需要什么条件
  • 外贸营销公司重庆公司网站seo
  • 建筑装修设计网站大全商城 网站有哪些功能模块
  • 永川做网站的上海法资企业名录
  • 做爰小视频网站wordpress调用特色
  • 网站空间ip地址徐州最大的网络平台公司
  • 企业网站定制公司云南网站建设哪家权威
  • 网页设计与网站建设全攻略pdf下载网页模板的网站
  • 下载的网站模板怎么去掉域名前的图标wordpress 登录 手机版
  • 佛山网站台江网站建设
  • 外贸网站推广和建站品牌型网站案例
  • 网站建设淘宝属于什么类目长沙品质网站建设优点
  • 新县住房和城乡规划建设网站越秀手机网站建设
  • php论坛网站建设教程模拟建筑4
  • 个人网站可以做商业吗做电子商务网站需要什么手续
  • 网站到期是否能换服务商海外平台有哪些
  • 如何建设网站24小时接单桂林尚品网络科技有限公司
  • 精美图表网站推荐佛山有哪些建设网站的公司
  • 网站幕布拍摄vs做网站各种控件的使用
  • 哪些企业会考虑做网站做网站备案什么意思
  • 高唐网站建设淮北论坛官网app
  • 专业营销网站建设广告公司创意取名
  • 广州网站关键词优化推广牡丹江做网站公司
  • 网站空间不足深圳中国有名的设计公司
  • 网站宽度设计上海有哪些大公司总部
  • 自学网站开发流程华为开发者模式怎么关闭