Full Code of aceld/zinx for AI

master 6fb5bd58d731 cached
233 files
532.8 KB
183.8k tokens
1240 symbols
1 requests
Download .txt
Showing preview only (588K chars total). Download the full file or copy to clipboard to get everything.
Repository: aceld/zinx
Branch: master
Commit: 6fb5bd58d731
Files: 233
Total size: 532.8 KB

Directory structure:
gitextract_ynwx33qg/

├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── reviewdog.yml
├── .gitignore
├── .golangci.yaml
├── LICENSE
├── Makefile
├── README-CN.md
├── README.md
├── examples/
│   ├── zinx_RequestPollMode/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── no_pool_mode_server/
│   │   │   └── NoPoolModeServer.go
│   │   └── pool_mode_server/
│   │       └── PoolModeServer.go
│   ├── zinx_async_op/
│   │   ├── async_op_apis/
│   │   │   └── user_async_api.go
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── db_model/
│   │   │   └── user_dao.go
│   │   ├── msg_struct/
│   │   │   └── user_login.go
│   │   ├── router/
│   │   │   └── login.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_client/
│   │   ├── Makefile
│   │   ├── build.sh
│   │   ├── c_router/
│   │   │   ├── hello.go
│   │   │   └── ping.go
│   │   ├── main.go
│   │   └── version
│   ├── zinx_client_old/
│   │   ├── Makefile
│   │   ├── build.sh
│   │   ├── c_router/
│   │   │   ├── hello.go
│   │   │   └── ping.go
│   │   ├── main.go
│   │   └── version
│   ├── zinx_closecallback/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── router/
│   │   │   └── ping_router.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_decoder/
│   │   ├── README.MD
│   │   ├── bili/
│   │   │   ├── README.MD
│   │   │   ├── main.go
│   │   │   └── router/
│   │   │       ├── bili0x10router.go
│   │   │       ├── bili0x13router.go
│   │   │       ├── bili0x14router.go
│   │   │       ├── bili0x15router.go
│   │   │       └── bili0x16router.go
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── router/
│   │   │   ├── htlvcrcbusinessrouter.go
│   │   │   └── tlvbusinessrouter.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_dynamic_bind/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server.go
│   ├── zinx_heartbeat/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── client_default/
│   │   │   └── client_default.go
│   │   ├── server/
│   │   │   ├── conf/
│   │   │   │   └── zinx.json
│   │   │   └── server.go
│   │   └── server_default/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server_default.go
│   ├── zinx_interceptor/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── interceptors/
│   │   │   └── interceptor_1.go
│   │   ├── router/
│   │   │   └── route.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_kcp/
│   │   ├── client/
│   │   │   └── kcp_client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_logger/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       ├── my_logger.go
│   │       └── server.go
│   ├── zinx_metrics/
│   │   ├── client/
│   │   │   ├── c1/
│   │   │   │   └── client.go
│   │   │   └── c2/
│   │   │       └── client.go
│   │   └── server/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server.go
│   ├── zinx_mutiport/
│   │   ├── client8999/
│   │   │   └── client.go
│   │   ├── client9000/
│   │   │   └── client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_new_router/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server.go
│   ├── zinx_protobuf/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_routerSlices/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── default_func_server/
│   │   │   └── server.go
│   │   ├── router_func_server/
│   │   │   └── server.go
│   │   └── router_group_server/
│   │       └── server.go
│   ├── zinx_server/
│   │   ├── Makefile
│   │   ├── build.sh
│   │   ├── conf/
│   │   │   └── zinx.json
│   │   ├── dockerfile
│   │   ├── main.go
│   │   ├── s_router/
│   │   │   ├── hello.go
│   │   │   └── ping.go
│   │   └── version
│   ├── zinx_tls/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_version_ex/
│   │   ├── ZinxV0.10Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.11Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.1Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   ├── ZinxV0.2Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   ├── ZinxV0.3Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   ├── ZinxV0.4Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       ├── conf/
│   │   │       │   └── zinx.json
│   │   │       └── server.go
│   │   ├── ZinxV0.5Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       ├── conf/
│   │   │       │   └── zinx.json
│   │   │       └── server.go
│   │   ├── ZinxV0.6Test-V0.7Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.8Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.9Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── datapackDemo/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   └── protoDemo/
│   │       ├── main.go
│   │       └── pb/
│   │           ├── Person.pb.go
│   │           └── Person.proto
│   └── zinx_websocket/
│       ├── client/
│       │   └── client.go
│       ├── minicode/
│       │   ├── .eslintrc.js
│       │   ├── app.js
│       │   ├── app.json
│       │   ├── app.wxss
│       │   ├── index/
│       │   │   ├── index.js
│       │   │   ├── index.json
│       │   │   ├── index.wxml
│       │   │   └── index.wxss
│       │   ├── package.json
│       │   ├── project.config.json
│       │   ├── project.private.config.json
│       │   └── sitemap.json
│       └── server/
│           └── server.go
├── go.mod
├── go.sum
├── logo/
│   └── zinxlogo.go
├── zasync_op/
│   ├── async_op.go
│   ├── async_op_result.go
│   └── async_worker.go
├── zconf/
│   ├── env.go
│   ├── userconf.go
│   └── zconf.go
├── zdecoder/
│   ├── crc.go
│   ├── htlvcrcdecoder.go
│   ├── ltvdecoder_little.go
│   └── tlvdecoder.go
├── ziface/
│   ├── iclient.go
│   ├── iconnection.go
│   ├── iconnmanager.go
│   ├── idatapack.go
│   ├── idecoder.go
│   ├── iheartbeat.go
│   ├── iinterceptor.go
│   ├── ilengthfield.go
│   ├── ilogger.go
│   ├── imessage.go
│   ├── imsghandler.go
│   ├── inotify.go
│   ├── irequest.go
│   ├── irouter.go
│   ├── iserver.go
│   └── options.go
├── zinterceptor/
│   ├── chain.go
│   ├── framedecoder.go
│   └── interceptor.go
├── zinx_app_demo/
│   └── mmo_game/
│       ├── README-CN.md
│       ├── README.md
│       ├── api/
│       │   ├── move.go
│       │   └── world_chat.go
│       ├── client_AI_robot.go
│       ├── conf/
│       │   └── zinx.json
│       ├── core/
│       │   ├── aoi.go
│       │   ├── aoi_test.go
│       │   ├── grid.go
│       │   ├── player.go
│       │   └── world_manager.go
│       ├── pb/
│       │   ├── build.sh
│       │   ├── msg.pb.go
│       │   └── msg.proto
│       └── server.go
├── zlog/
│   ├── default.go
│   ├── logger_core.go
│   ├── stdzlog.go
│   └── zlog_test.go
├── znet/
│   ├── acceptdelay.go
│   ├── acceptdelay_test.go
│   ├── callbacks.go
│   ├── callbacks_test.go
│   ├── chainbuilder.go
│   ├── client.go
│   ├── connection.go
│   ├── connmanager.go
│   ├── defaultrouterfunc.go
│   ├── heartbeat.go
│   ├── kcp_connection.go
│   ├── msghandler.go
│   ├── options.go
│   ├── request.go
│   ├── request_func.go
│   ├── router.go
│   ├── routerSilces_test.go
│   ├── server.go
│   ├── server_test.go
│   └── ws_connection.go
├── znotify/
│   ├── notify.go
│   └── notify_test.go
├── zpack/
│   ├── datapack_ltv_littleendian.go
│   ├── datapack_tlv_bigendian.go
│   ├── datapack_tlv_bigendian_test.go
│   ├── message.go
│   └── packfactory.go
├── ztimer/
│   ├── delayfunc.go
│   ├── delayfunc_test.go
│   ├── timer.go
│   ├── timer_test.go
│   ├── timerscheduler.go
│   ├── timerscheduler_test.go
│   ├── timewheel.go
│   └── timewheel_test.go
└── zutils/
    ├── hash.go
    ├── shard_lock_map.go
    ├── shard_lock_map_bench_test.go
    ├── shard_lock_map_test.go
    ├── snowflake_uuid.go
    ├── snowflake_uuid_test.go
    └── witer.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
*.aspx linguist-language=Go


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [aceld] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
#custom: https://user-images.githubusercontent.com/7778936/179700249-a89a82e1-d851-4b3d-a43e-c5a91b7d128d.png # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .github/workflows/reviewdog.yml
================================================
name: reviewdog
on: [pull_request]

permissions:
  contents: read
  pull-requests: write

jobs:
  golangci-lint:
    runs-on: ubuntu-latest
    name: runner / golangci-lint
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@v3
      - name: golangci-lint
        uses: reviewdog/action-golangci-lint@dd3fda91790ca90e75049e5c767509dc0ec7d99b
        with:
          github_token: ${{ secrets.github_token }}
          # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
          reporter: github-pr-review
          # Report all results.
          filter_mode: nofilter
          # Exit with 1 when it finds at least one finding.
          fail_on_error: true
          #golangci_lint_flags
          golangci_lint_version: v1.64.7

================================================
FILE: .gitignore
================================================
.idea
.vscode

/zinx_app_demo/mmo_game/game_client/client_Data/
/zinx_app_demt/mmo_game/mmo_game_log/
*.log

### bin
examples/zinx_server/zinx_server
examples/zinx_server/server
examples/zinx_client/client

.DS_Store


log

/examples/zinx_websocket/minicode/node_modules
/examples/zinx_websocket/minicode/miniprogram_npm

rebase


================================================
FILE: .golangci.yaml
================================================
run:
  timeout: 30m
  skip-dirs:
  - examples

linters:
  disable-all: true
  enable:
  #- unused
  - ineffassign
  - goimports
  - gofmt
  - misspell
  - unparam
  - unconvert
  - govet
  # - errcheck
  - staticcheck

linters-settings:
  staticcheck:
    go: "1.17"
    checks:
    - "all"
    - "-SA1019"

  unused:
    go: "1.17"


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2024 Aceld(刘丹冰)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================

.PHONY: build

SERVICE := zinx
CUR_PWD := $(shell pwd)

SERVER_DEMO_PATH := $(CUR_PWD)/examples/zinx_server
CLIENT_DEMO_PATH := $(CUR_PWD)/examples/zinx_client
SERVER_DEMO_BIN := $(SERVER_DEMO_PATH)/server
CLIENT_DEMO_BIN := $(CLIENT_DEMO_PATH)/client

AUTHOR := $(shell git log --pretty=format:"%an"|head -n 1)
VERSION := $(shell git rev-list HEAD | head -1)
BUILD_INFO := $(shell git log --pretty=format:"%s" | head -1)
BUILD_DATE := $(shell date +%Y-%m-%d\ %H:%M:%S)

export GO111MODULE=on

LD_FLAGS='-X "$(SERVICE)/version.TAG=$(TAG)" -X "$(SERVICE)/version.VERSION=$(VERSION)" -X "$(SERVICE)/version.AUTHOR=$(AUTHOR)" -X "$(SERVICE)/version.BUILD_INFO=$(BUILD_INFO)" -X "$(SERVICE)/version.BUILD_DATE=$(BUILD_DATE)"'

TEST_FILES := znet/acceptdelay_test.go znet/acceptdelay.go

default: build

build:
	go build  -ldflags $(LD_FLAGS) -gcflags "-N"  -o $(SERVER_DEMO_BIN) $(SERVER_DEMO_PATH)/main.go
	go build  -ldflags $(LD_FLAGS) -gcflags "-N"  -o $(CLIENT_DEMO_BIN) $(CLIENT_DEMO_PATH)/main.go

test:
	go test -v -cover $(TEST_FILES)
clean:
	rm $(SERVER_DEMO_BIN)
	rm $(CLIENT_DEMO_BIN)


================================================
FILE: README-CN.md
================================================
# <img width="80px" src="https://s2.ax1x.com/2019/10/09/u4yHo9.png" /> 

[English](README.md) | 简体中文

[![License](https://img.shields.io/badge/License-MIT-black.svg)](LICENSE)
[![Discord](https://img.shields.io/badge/zinx-Discord在线社区-blue.svg)](https://discord.gg/xQ8Xxfyfcz)
[![Gitter](https://img.shields.io/badge/zinx-Gitter在线交流-green.svg)](https://gitter.im/zinx_go/community)
[![zinx tutorial](https://img.shields.io/badge/Zinx教程-YuQue-red.svg)](https://www.yuque.com/aceld/npyr8s/bgftov)
[![Original Book of Zinx](https://img.shields.io/badge/原创书籍-YuQue-black.svg)](https://www.yuque.com/aceld)

Zinx 是一个基于Golang的轻量级并发服务器框架

## 开发者文档

[ < Zinx Wiki : English > ](https://github.com/aceld/zinx/wiki)

[ < Zinx 文档 : 简体中文> ](https://www.yuque.com/aceld/tsgooa/sbvzgczh3hqz8q3l)

> **说明**:目前zinx已经在很多企业进行开发使用,具体使用领域包括:后端模块的消息中转、长连接游戏服务器、Web框架中的消息处理插件等。zinx的定位是代码简洁,让更多的开发者迅速的了解框架的内脏细节并且可以快速基于zinx DIY(二次开发)一款适合自己企业场景的模块。

---
## zinx源码地址
| platform | Entry | 
| ---- | ---- | 
|Github| https://github.com/aceld/zinx |
|Gitcode|https://gitcode.com/aceld/zinx|
|Gitee|https://gitee.com/Aceld/zinx|

### 官网
http://zinx.me

---

## 在线开发教程

### 文字教程

| platform | Entry | 
| ---- | ---- | 
| <img src="https://user-images.githubusercontent.com/7778936/236784004-b6d99e26-b1ab-4bc3-988e-7a46108b85fe.png" width = "100" height = "100" alt="" align=center />| [Zinx Framework tutorial-Lightweight server based on Golang](https://dev.to/aceld/1building-basic-services-with-zinx-framework-296e)| 
|<img src="https://user-images.githubusercontent.com/7778936/236784168-6528a9b8-d37b-4b02-a37c-b9988d7508d8.jpeg" width = "100" height = "100" alt="" align=center />|[《Golang轻量级并发服务器框架zinx》](https://www.yuque.com/aceld)|


### 视频教程

| platform | online video | 
| ---- | ---- | 
| <img src="https://s1.ax1x.com/2022/09/22/xFePUK.png" width = "100" height = "100" alt="" align=center />| [![zinx-BiliBili](https://s2.ax1x.com/2019/10/13/uv340S.jpg)](https://www.bilibili.com/video/av71067087)| 
| <img src="https://s1.ax1x.com/2022/09/22/xFesxJ.png" width = "100" height = "80" alt="" align=center />  | [![zinx-BiliBili](https://s2.ax1x.com/2019/10/13/uv340S.jpg)](https://www.douyin.com/video/6983301202939333891) |
| <img src="https://s1.ax1x.com/2022/09/23/xkQcng.png" width = "100" height = "100" alt="" align=center />| [![zinx-youtube](https://s2.ax1x.com/2019/10/14/KSurCR.jpg)](https://www.youtube.com/watch?v=U95iF-HMWsU&list=PL_GrAPKmuajzeNI8HBTi-k5NQO1g0rM-A)| 

    
## 一、写在前面

我们为什么要做Zinx,Golang目前在服务器的应用框架很多,但是应用在游戏领域或者其他长连接的领域的轻量级企业框架甚少。

设计Zinx的目的是我们可以通过Zinx框架来了解基于Golang编写一个TCP服务器的整体轮廓,让更多的Golang爱好者能深入浅出的去学习和认识这个领域。

Zinx框架的项目制作采用编码和学习教程同步进行,将开发的全部递进和迭代思维带入教程中,而不是一下子给大家一个非常完整的框架去学习,让很多人一头雾水,不知道该如何学起。

教程会一个版本一个版本迭代,每个版本的添加功能都是微小的,让一个服务框架小白,循序渐进的曲线方式了解服务器框架的领域。

当然,最后希望Zinx会有更多的人加入,给我们提出宝贵的意见,让Zinx成为真正的解决企业的服务器框架!在此感谢您的关注!




## 二、初探Zinx架构
![Zinx框架](https://user-images.githubusercontent.com/7778936/220058446-0ad45112-2225-4b71-b0d8-69a7f3cee5ca.jpg)

![流程图](https://github.com/wenyoufu/testaaaaaa/blob/abc8a50078a86aed37e8af6082d1d867bc165c32/%E6%9C%AA%E5%91%BD%E5%90%8D%E6%B5%81%E7%A8%8B%E5%9B%BE%20(1).jpg?raw=true)
![zinx-start](https://user-images.githubusercontent.com/7778936/126594039-98dddd10-ec6a-4881-9e06-a09ec34f1af7.gif)



## 三、Zinx开发接口文档


### (1)快速开始

[<Zinx的Tcp调试工具>](https://github.com/xxl6097/tcptest)

**版本**
Golang 1.17+

DownLoad zinx Source

```bash
$go get github.com/aceld/zinx
```

> note: Golang Version 1.17+

#### Zinx-Server
```go
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// PingRouter MsgId=1的路由
type PingRouter struct {
	znet.BaseRouter
}

//Ping Handle MsgId=1的路由处理方法
func (r *PingRouter) Handle(request ziface.IRequest) {
	//读取客户端的数据
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}

func main() {
	//1 创建一个server服务
	s := znet.NewServer()

	//2 配置路由
	s.AddRouter(1, &PingRouter{})

	//3 启动服务
	s.Serve()
}

```

Run Server

```bash
$ go run server.go
```

```bash
                                        
              ██                        
              ▀▀                        
 ████████   ████     ██▄████▄  ▀██  ██▀ 
     ▄█▀      ██     ██▀   ██    ████   
   ▄█▀        ██     ██    ██    ▄██▄   
 ▄██▄▄▄▄▄  ▄▄▄██▄▄▄  ██    ██   ▄█▀▀█▄  
 ▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀  ▀▀    ▀▀  ▀▀▀  ▀▀▀ 
                                        
┌──────────────────────────────────────────────────────┐
│ [Github] https://github.com/aceld                    │
│ [tutorial] https://www.yuque.com/aceld/npyr8s/bgftov │
└──────────────────────────────────────────────────────┘
[Zinx] Version: V1.0, MaxConn: 12000, MaxPacketSize: 4096
===== Zinx Global Config =====
TCPServer: <nil>
Host: 0.0.0.0
TCPPort: 8999
Name: ZinxServerApp
Version: V1.0
MaxPacketSize: 4096
MaxConn: 12000
WorkerPoolSize: 10
MaxWorkerTaskLen: 1024
MaxMsgChanLen: 1024
ConfFilePath: /Users/Aceld/go/src/zinx-usage/quick_start/conf/zinx.json
LogDir: /Users/Aceld/go/src/zinx-usage/quick_start/log
LogFile: 
LogIsolationLevel: 0
HeartbeatMax: 10
==============================
2023/03/09 18:39:49 [INFO]msghandler.go:61: Add api msgID = 1
2023/03/09 18:39:49 [INFO]server.go:112: [START] Server name: ZinxServerApp,listenner at IP: 0.0.0.0, Port 8999 is starting
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 0 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 1 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 3 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 2 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 4 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 6 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 7 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 8 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 9 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 5 is started.
2023/03/09 18:39:49 [INFO]server.go:134: [START] start Zinx server  ZinxServerApp succ, now listenning...

```



#### Zinx-Client

```go
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"time"
)

//客户端自定义业务
func pingLoop(conn ziface.IConnection) {
	for {
		err := conn.SendMsg(1, []byte("Ping...Ping...Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

//创建连接的时候执行
func onClientStart(conn ziface.IConnection) {
	fmt.Println("onClientStart is Called ... ")
	go pingLoop(conn)
}

func main() {
	//创建Client客户端
	client := znet.NewClient("127.0.0.1", 8999)

	//设置连接建立成功后的钩子函数
	client.SetOnConnStart(onClientStart)

	//启动客户端
	client.Start()

	//防止进程退出,等待中断信号
	select {}
}

```

Run Client

```bash
$ go run client.go 
2023/03/09 19:04:54 [INFO]client.go:73: [START] Zinx Client LocalAddr: 127.0.0.1:55294, RemoteAddr: 127.0.0.1:8999
2023/03/09 19:04:54 [INFO]connection.go:354: ZINX CallOnConnStart....
```

Terminal of Zinx Print:
```bash
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
...
```


### (2)Zinx配置文件
```json
{
  "Name":"zinx v-0.10 demoApp",
  "Host":"0.0.0.0",
  "TCPPort":9090,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogDir": "./mylog",
  "LogFile":"app.log",
  "LogSaveDays":15,
  "LogCons": true,
  "LogIsolationLevel":0
}
```

`Name`:服务器应用名称

`Host`:服务器IP

`TcpPort`:服务器监听端口

`MaxConn`:允许的客户端连接最大数量

`WorkerPoolSize`:工作任务池最大工作Goroutine数量

`LogDir`: 日志文件夹

`LogFile`: 日志文件名称(如果不提供,则日志信息打印到Stderr)

`LogIsolationLevel`: 日志隔离级别 0:全开, 1:关debug, 2:关debug/info, 3:关debug/info/warn 

---

#### 开发者
| **Zinx**                                               | **开发者**  |
|--------------------------------------------------------| ----  | 
| [zinx](https://github.com/aceld/zinx)                  |刘丹冰([@aceld](https://github.com/aceld)) 张超([@zhngcho](https://github.com/zhngcho)) 高智辉Roger([@adsian](https://github.com/adsian)) 胡贵建([@huguijian](https://github.com/huguijian)) 张继瑀([@kstwoak](https://github.com/kstwoak)) 夏小力([@xxl6097](https://github.com/xxl6097)) 李志成([@clukboy](https://github.com/clukboy))姚承政([@hcraM41](https://github.com/hcraM41))李国杰([@LI-GUOJIE](https://github.com/LI-GUOJIE))余喆宁([@YanHeDoki](https://github.com/YanHeDoki))|
| [moke-kit(微服务框架)](https://github.com/GStones/moke-kit) |GStones([@GStones](https://github.com/GStones))|
| [zinx(C++)](https://github.com/marklion/zinx)          |刘洋([@marklion](https://github.com/marklion))|
| [zinx(Lua)](https://github.com/huqitt/zinx-lua)        |胡琪([@huqitt](https://github.com/huqitt))|
| [ginx(Java)](https://github.com/ModuleCode/ginx)       |ModuleCode([@ModuleCode](https://github.com/ModuleCode))|

---

感谢所有为zinx贡献的开发者


<a href="https://github.com/aceld/zinx/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=aceld/zinx" />
</a>    


---
### 关于作者:

作者:`Aceld(刘丹冰)`

`mail`:
[danbing.at@gmail.com](mailto:danbing.at@gmail.com)

`github`:
[https://github.com/aceld](https://github.com/aceld)

`原创书籍`:
[https://www.yuque.com/aceld](https://www.yuque.com/aceld)


### 加入Zinx技术社区

| platform | Entry | 
| ---- | ---- | 
| <img src="https://user-images.githubusercontent.com/7778936/236775008-6bd488e3-249a-4d43-8885-7e3889e11e2d.png" width = "100" height = "100" alt="" align=center />| https://discord.gg/xQ8Xxfyfcz| 
| <img src="https://user-images.githubusercontent.com/7778936/236775137-5381f8a6-f534-49c4-8628-e52bf245c3bc.jpeg" width = "100" height = "100" alt="" align=center />  | 加微信: `ace_ld`  或扫二维码,备注`zinx`即可。</br><img src="https://user-images.githubusercontent.com/7778936/236781258-2f0371bd-5797-49e8-a74c-680e9f15843d.png" width = "150" height = "150" alt="" align=center /> |
|<img src="https://user-images.githubusercontent.com/7778936/236778547-9cdadfb6-0f62-48ac-851a-b940389038d0.jpeg" width = "100" height = "100" alt="" align=center />|<img src="https://s1.ax1x.com/2020/07/07/UFyUdx.th.jpg" height = "150"  alt="" align=center /> **WeChat Public Account** |
|<img src="https://user-images.githubusercontent.com/7778936/236779000-70f16c8f-0eec-4b5f-9faa-e1d5229a43e0.png" width = "100" height = "100" alt="" align=center />|<img src="https://s1.ax1x.com/2020/07/07/UF6Y9S.th.png" width = "150" height = "150" alt="" align=center /> **QQ Group** |


================================================
FILE: README.md
================================================
# <img width="80px" src="https://s2.ax1x.com/2019/10/09/u4yHo9.png" />
English | [简体中文](README-CN.md)

[![License](https://img.shields.io/badge/License-MIT-black.svg)](LICENSE)
[![Discord](https://img.shields.io/badge/zinx-Discord-blue.svg)](https://discord.gg/xQ8Xxfyfcz)
[![Gitter](https://img.shields.io/badge/zinx-Gitter-green.svg)](https://gitter.im/zinx_go/community) 
[![zinx tutorial](https://img.shields.io/badge/ZinxTutorial-YuQue-red.svg)](https://www.yuque.com/aceld/npyr8s/bgftov) 
[![Original Book of Zinx](https://img.shields.io/badge/OriginalBook-YuQue-black.svg)](https://www.yuque.com/aceld)

Zinx is a lightweight concurrent server framework based on Golang.

##  Document 

[ < Zinx Wiki : English > ](https://github.com/aceld/zinx/wiki)

[ < Zinx 文档 : 简体中文> ](https://www.yuque.com/aceld/tsgooa/sbvzgczh3hqz8q3l)


> **Note**: 
> Zinx has been widely used in many enterprises for development purposes, including message forwarding for backend modules, long-linked game servers, and message handling plugins for web frameworks. 
> Zinx is positioned as a framework with concise code that allows developers to quickly understand the internal details of the framework and easily customize it based on their own enterprise scenarios.

---
## Source of Zinx
| platform | Entry | 
| ---- | ---- | 
|Github| https://github.com/aceld/zinx |
|Gitcode|https://gitcode.com/aceld/zinx|
|Gitee|https://gitee.com/Aceld/zinx|

### Website
http://zinx.me

---
## Online Tutorial

| platform | Entry | 
| ---- | ---- | 
| <img src="https://user-images.githubusercontent.com/7778936/236784004-b6d99e26-b1ab-4bc3-988e-7a46108b85fe.png" width = "100" height = "100" alt="" align=center />| [Zinx Framework tutorial-Lightweight server based on Golang](https://dev.to/aceld/1building-basic-services-with-zinx-framework-296e)| 
|<img src="https://user-images.githubusercontent.com/7778936/236784168-6528a9b8-d37b-4b02-a37c-b9988d7508d8.jpeg" width = "100" height = "100" alt="" align=center />|[《Golang轻量级并发服务器框架zinx》](https://www.yuque.com/aceld)|


## Online Tutorial Video

| platform | online video | 
| ---- | ---- | 
| <img src="https://s1.ax1x.com/2022/09/22/xFePUK.png" width = "100" height = "100" alt="" align=center />| [![zinx-BiliBili](https://s2.ax1x.com/2019/10/13/uv340S.jpg)](https://www.bilibili.com/video/av71067087)| 
| <img src="https://github.com/user-attachments/assets/4c401abd-7807-432a-968e-36ce0e74349c" width = "100" height = "100" alt="" align=center />  | [![zinx-BiliBili](https://s2.ax1x.com/2019/10/13/uv340S.jpg)](https://www.douyin.com/video/6983301202939333891) |
| <img src="https://s1.ax1x.com/2022/09/23/xkQcng.png" width = "100" height = "100" alt="" align=center />| [![zinx-youtube](https://s2.ax1x.com/2019/10/14/KSurCR.jpg)](https://www.youtube.com/watch?v=U95iF-HMWsU&list=PL_GrAPKmuajzeNI8HBTi-k5NQO1g0rM-A)| 





## I. One word that has been said before

Why did we create Zinx? Although there are many Golang application frameworks for servers, there are few lightweight enterprise frameworks applied in the gaming or other long-linked fields.

The purpose of designing Zinx is to provide a complete outline of how to write a TCP server based on Golang, so that more Golang enthusiasts can learn and understand this field in a straightforward manner.

The development of the Zinx framework project is synchronized with the creation of learning tutorials, and all the incremental and iterative thinking involved in the development process is incorporated into the tutorials. This approach avoids overwhelming beginners with a complete framework that they may find difficult to grasp all at once.

The tutorials will be iterated version by version, with each version adding small increments of functionality, allowing a beginner to gradually and comprehensively learn about the field of server frameworks.

Of course, we hope that more people will join Zinx and provide us with valuable feedback, enabling Zinx to become a truly enterprise-level server framework. Thank you for your attention!



## II. Zinx architecture
![Zinx框架](https://user-images.githubusercontent.com/7778936/220058446-0ad45112-2225-4b71-b0d8-69a7f3cee5ca.jpg)

![流程图](https://raw.githubusercontent.com/wenyoufu/testaaaaaa/master/%E6%B5%81%E7%A8%8B%E5%9B%BE-en.jpg)
![zinx-start](https://user-images.githubusercontent.com/7778936/126594039-98dddd10-ec6a-4881-9e06-a09ec34f1af7.gif)



## III. Zinx development API documentation


### (1) QuickStart

[<Zinx's TCP Debugging Tool>](https://github.com/xxl6097/tcptest)

DownLoad zinx Source

```bash
$go get github.com/aceld/zinx
```

> note: Golang Version 1.17+

#### Zinx-Server
```go
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// PingRouter MsgId=1 
type PingRouter struct {
	znet.BaseRouter
}

//Ping Handle MsgId=1
func (r *PingRouter) Handle(request ziface.IRequest) {
	//read client data
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}

func main() {
	//1 Create a server service
	s := znet.NewServer()

	//2 configure routing
	s.AddRouter(1, &PingRouter{})

	//3 start service
	s.Serve()
}
```

Run Server

```bash
$ go run server.go
```

```bash
                                        
              ██                        
              ▀▀                        
 ████████   ████     ██▄████▄  ▀██  ██▀ 
     ▄█▀      ██     ██▀   ██    ████   
   ▄█▀        ██     ██    ██    ▄██▄   
 ▄██▄▄▄▄▄  ▄▄▄██▄▄▄  ██    ██   ▄█▀▀█▄  
 ▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀  ▀▀    ▀▀  ▀▀▀  ▀▀▀ 
                                        
┌──────────────────────────────────────────────────────┐
│ [Github] https://github.com/aceld                    │
│ [tutorial] https://www.yuque.com/aceld/npyr8s/bgftov │
└──────────────────────────────────────────────────────┘
[Zinx] Version: V1.0, MaxConn: 12000, MaxPacketSize: 4096
===== Zinx Global Config =====
Host: 0.0.0.0
TCPPort: 8999
Name: ZinxServerApp
Version: V1.0
MaxPacketSize: 4096
MaxConn: 12000
WorkerPoolSize: 10
MaxWorkerTaskLen: 1024
MaxMsgChanLen: 1024
ConfFilePath: /Users/Aceld/go/src/zinx-usage/quick_start/conf/zinx.json
LogDir: /Users/Aceld/go/src/zinx-usage/quick_start/log
LogFile: 
LogIsolationLevel: 0
HeartbeatMax: 10
==============================
2023/03/09 18:39:49 [INFO]msghandler.go:61: Add api msgID = 1
2023/03/09 18:39:49 [INFO]server.go:112: [START] Server name: ZinxServerApp,listenner at IP: 0.0.0.0, Port 8999 is starting
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 0 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 1 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 3 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 2 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 4 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 6 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 7 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 8 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 9 is started.
2023/03/09 18:39:49 [INFO]msghandler.go:66: Worker ID = 5 is started.
2023/03/09 18:39:49 [INFO]server.go:134: [START] start Zinx server  ZinxServerApp succ, now listenning...

```



#### Zinx-Client

```go
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"time"
)

//Client custom business
func pingLoop(conn ziface.IConnection) {
	for {
		err := conn.SendMsg(1, []byte("Ping...Ping...Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

//Executed when a connection is created
func onClientStart(conn ziface.IConnection) {
	fmt.Println("onClientStart is Called ... ")
	go pingLoop(conn)
}

func main() {
	//Create a client client
	client := znet.NewClient("127.0.0.1", 8999)

	//Set the hook function after the link is successfully established
	client.SetOnConnStart(onClientStart)

	//start the client
	client.Start()

	//Prevent the process from exiting, waiting for an interrupt signal
	select {}
}
```

Run Client

```bash
$ go run client.go 
2023/03/09 19:04:54 [INFO]client.go:73: [START] Zinx Client LocalAddr: 127.0.0.1:55294, RemoteAddr: 127.0.0.1:8999
2023/03/09 19:04:54 [INFO]connection.go:354: ZINX CallOnConnStart....
```

Terminal of Zinx Print:
```bash
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
...
```


### (2) Zinx configuration file
```json
{
  "Name":"zinx v-0.10 demoApp",
  "Host":"0.0.0.0",
  "TCPPort":9090,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogDir": "./mylog",
  "LogFile":"app.log",
  "LogSaveDays":15,
  "LogCons": true,
  "LogIsolationLevel":0
}
```

`Name`:Server Application Name

`Host`:Server IP

`TcpPort`:Server listening port

`MaxConn`:Maximum number of client links allowed

`WorkerPoolSize`:Maximum number of working Goroutines in the work task pool

`LogDir`: Log folder

`LogFile`: Log file name (if not provided, log information is printed to Stderr)

`LogIsolationLevel`: Log Isolation Level -0: Full On 1: Off debug 2: Off debug/info 3: Off debug/info/warn

---


#### Developers

| **Zinx**                                                       | **Authors**  |
|----------------------------------------------------------------| ----  | 
| [zinx](https://github.com/aceld/zinx)                          |刘丹冰([@aceld](https://github.com/aceld)) 张超([@zhngcho](https://github.com/zhngcho)) 高智辉Roger([@adsian](https://github.com/adsian)) 胡贵建([@huguijian](https://github.com/huguijian)) 张继瑀([@kstwoak](https://github.com/kstwoak)) 夏小力([@xxl6097](https://github.com/xxl6097)) 李志成([@clukboy](https://github.com/clukboy))姚承政([@hcraM41](https://github.com/hcraM41))李国杰([@LI-GUOJIE](https://github.com/LI-GUOJIE))余喆宁([@YanHeDoki](https://github.com/YanHeDoki))|
| [moke-kit(Microservices)](https://github.com/GStones/moke-kit) |GStones([@GStones](https://github.com/GStones))|
| [zinx(C++)](https://github.com/marklion/zinx)                  |刘洋([@marklion](https://github.com/marklion))|
| [zinx(Lua)](https://github.com/huqitt/zinx-lua)                |胡琪([@huqitt](https://github.com/huqitt))|
| [ginx(Java)](https://github.com/ModuleCode/ginx)               |ModuleCode([@ModuleCode](https://github.com/ModuleCode))|

---

Thanks to all the developers who contributed to Zinx!

<a href="https://github.com/aceld/zinx/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=aceld/zinx" />
</a>    


---

### About the author

`name`:`Aceld(刘丹冰)`

`mail`:
[danbing.at@gmail.com](mailto:danbing.at@gmail.com)

`github`:
[https://github.com/aceld](https://github.com/aceld)

`original work`:
[https://www.yuque.com/aceld](https://www.yuque.com/aceld)

### Join the Zinx community 

| platform | Entry | 
| ---- | ---- | 
| <img src="https://user-images.githubusercontent.com/7778936/236775008-6bd488e3-249a-4d43-8885-7e3889e11e2d.png" width = "100" height = "100" alt="" align=center />| https://discord.gg/xQ8Xxfyfcz| 
| <img src="https://user-images.githubusercontent.com/7778936/236775137-5381f8a6-f534-49c4-8628-e52bf245c3bc.jpeg" width = "100" height = "100" alt="" align=center />  | 加微信: `ace_ld`  或扫二维码,备注`zinx`即可。</br><img src="https://user-images.githubusercontent.com/7778936/236781258-2f0371bd-5797-49e8-a74c-680e9f15843d.png" width = "150" height = "150" alt="" align=center /> |
|<img src="https://user-images.githubusercontent.com/7778936/236778547-9cdadfb6-0f62-48ac-851a-b940389038d0.jpeg" width = "100" height = "100" alt="" align=center />|<img src="https://s1.ax1x.com/2020/07/07/UFyUdx.th.jpg" height = "150"  alt="" align=center /> **WeChat Public Account** |
|<img src="https://user-images.githubusercontent.com/7778936/236779000-70f16c8f-0eec-4b5f-9faa-e1d5229a43e0.png" width = "100" height = "100" alt="" align=center />|<img src="https://github.com/aceld/zinx/assets/7778936/461b409f-6337-48a8-826b-a7a746aaee31" width = "150" height = "150" alt="" align=center /> **QQ Group** |


================================================
FILE: examples/zinx_RequestPollMode/client/client.go
================================================
package main

import (
	"fmt"
	"os"
	"os/signal"
	"time"

	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// Custom business logic of the client (客户端自定义业务)
func business(conn ziface.IConnection) {

	for i := 0; i < 100; i++ {
		err := conn.SendMsg(1, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		err = conn.SendMsg(2, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

	}
}

// Function to execute when the connection is created (创建连接的时候执行)
func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	// Set two connection properties after the connection is created (设置两个连接属性,在连接创建之后)
	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

// Function to execute when the connection is lost (连接断开的时候执行)
func DoClientConnectedLost(conn ziface.IConnection) {
	// Get the Name and Home properties of the connection before it is destroyed
	// (在连接销毁之前,查询conn的Name,Home属性)
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Debug("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Debug("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	// Create a client handle using Zinx's Method (创建一个Client句柄,使用Zinx的方法)
	client := znet.NewClient("127.0.0.1", 8999)

	// Set the business logic to execute when the connection is created or lost
	// (添加首次建立连接时的业务)
	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	// Register routers for the messages received from the server
	// (注册收到服务器消息业务路由)
	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	// Start the client
	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_RequestPollMode/no_pool_mode_server/NoPoolModeServer.go
================================================
package main

import (
	"fmt"
	"time"

	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// 如果不使用对象池模式则可以直接传递但是产生大量的 Request 对象

func NoPoll1(request ziface.IRequest) {
	request.Set("num", 1)
	go NoPoll2(request)
}

func NoPoll2(request ziface.IRequest) {
	time.Sleep(time.Second * 3)
	get, _ := request.Get("num")
	fmt.Printf("num:%v \n", get)

}

func NoPoll4(request ziface.IRequest) {
	// 非对象池模式永远不会影响原本的 Request
	request.Set("num", 3)
}

func main() {

	// 关闭 Request 对象池模式
	server := znet.NewUserConfServer(&zconf.Config{RouterSlicesMode: true, TCPPort: 8999, Host: "127.0.0.1", RequestPoolMode: false})
	server.AddRouterSlices(1, NoPoll1)
	server.AddRouterSlices(2, NoPoll4)
	server.Serve()
}


================================================
FILE: examples/zinx_RequestPollMode/pool_mode_server/PoolModeServer.go
================================================
package main

import (
	"fmt"
	"time"

	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

func Poll1(request ziface.IRequest) {
	// 如果需要连接信息
	request.Set("conn", request.GetConnection())
	request.Set("num", 1)
	fmt.Printf("request 1 addr:%p,conn:%p \n", &request, request.GetConnection())

	// 需要新线程同时也需要上下文的情况,则需要调用 copy 方法拷贝一份
	cp := request.Copy()
	go Poll2(cp)

	// 如果不使用 copy 方法拷贝对象则会出现同一个对象但是信息可能不一致的问题,不启动 poll2 会更直接
	go Poll3(request)
}

func Poll2(request ziface.IRequest) {
	defer func() {
		if err := recover(); err != nil {
			// 接收一个panic
			fmt.Println(err)
		}

	}()
	get_conn, ok := request.Get("conn")
	if ok {
		// 如果直接取用则会导致空指针
		request.GetConnection().GetConnID()
		//  打印出的 Request 对象的地址是不一致的
		conn := get_conn.(ziface.IConnection)
		fmt.Printf("request copy addr:%p,conn:%p \n", &request, conn)
		// conn.sendMsg()
	}
}

// 如果请求的次数多,则开启对象池且直接传递不copy Request 就可能导致值不一致
func Poll3(request ziface.IRequest) {
	time.Sleep(time.Second * 3)
	get, _ := request.Get("num")
	// 池化对象如果直接传递被影响可能随机打印被修改的值 3
	fmt.Printf("num:%v \n", get)

}

func Poll4(request ziface.IRequest) {
	// 影响原本的 request 对象
	request.Set("num", 3)
}

func main() {

	// 开启 Request 对象池模式
	server := znet.NewUserConfServer(&zconf.Config{RouterSlicesMode: true, TCPPort: 8999, Host: "127.0.0.1", RequestPoolMode: true})
	server.AddRouterSlices(1, Poll1)
	server.AddRouterSlices(2, Poll4)
	server.Serve()
}


================================================
FILE: examples/zinx_async_op/async_op_apis/user_async_api.go
================================================
package async_op_apis

import (
	"github.com/aceld/zinx/examples/zinx_async_op/db_model"
	"github.com/aceld/zinx/zasync_op"
	"github.com/aceld/zinx/ziface"
)

func AsyncUserSaveData(request ziface.IRequest) *zasync_op.AsyncOpResult {

	opId := 1 // player's unique identifier Id (玩家的唯一标识Id)
	asyncResult := zasync_op.NewAsyncOpResult(request.GetConnection())

	zasync_op.Process(
		int(opId),
		func() {
			// perform db operation (执行db操作)
			user := db_model.SaveUserData()

			// set async return result (设置异步返回结果)
			asyncResult.SetReturnedObj(user)

			// test active exception (测试主动异常)
			/*
				a := 0
				b := 1
				c := b / a
				fmt.Println(c)
			*/
		},
	)

	return asyncResult
}


================================================
FILE: examples/zinx_async_op/client/client.go
================================================
package main

import (
	"fmt"
	"io"
	"net"

	"github.com/aceld/zinx/zpack"
)

func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:8999")
	if err != nil {
		fmt.Println("client start err, exit!", err)
		return
	}

	dp := zpack.NewDataPack()
	msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("async_op_router test=========>")))
	_, err = conn.Write(msg)
	if err != nil {
		fmt.Println("write error err ", err)
		return
	}

	for {
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData)
		if err != nil {
			fmt.Println("client read head err: ", err)
			return
		}

		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("client unpack head err: ", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("client unpack data err")
				return
			}

			fmt.Printf("==> Client receive Msg: ID = %d, len = %d , data = %s\n", msg.ID, msg.DataLen, msg.Data)
		}
	}

}


================================================
FILE: examples/zinx_async_op/db_model/user_dao.go
================================================
package db_model

import (
	"time"

	"github.com/aceld/zinx/zlog"
)

type UserModel struct {
	UserId     uint32
	UpdateTime int64
	Name       string
}

func SaveUserData() *UserModel {
	zlog.Debug("SaveUserData IN=================>222")

	time.Sleep(time.Second * 2) // 模拟db操作需要2秒时间
	user := &UserModel{1, time.Now().Unix(), "14March"}

	zlog.Debug("SaveUserData OUT==================>222")
	return user
}


================================================
FILE: examples/zinx_async_op/msg_struct/user_login.go
================================================
package msg_struct

type MsgLoginResponse struct {
	UserId    uint32
	UserName  string
	ErrorCode int
}


================================================
FILE: examples/zinx_async_op/router/login.go
================================================
package router

import (
	"encoding/json"
	"time"

	"github.com/aceld/zinx/examples/zinx_async_op/async_op_apis"
	"github.com/aceld/zinx/examples/zinx_async_op/db_model"
	"github.com/aceld/zinx/examples/zinx_async_op/msg_struct"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type LoginRouter struct {
	znet.BaseRouter
}

func (hr *LoginRouter) Handle(request ziface.IRequest) {
	zlog.Debug("AsyncOpRouter Handle IN ===>111")

	asyncResult := async_op_apis.AsyncUserSaveData(request) // // Test DB asynchronous operation(测试DB异步操作)

	// 测试:执行了一大推业务逻辑,才设置回调函数
	// Test: A lot of business logic is executed before setting the callback function
	time.Sleep(1 * time.Second)

	// Asynchronous callback (异步回调)
	asyncResult.OnComplete(func() {
		zlog.Debug("OnComplete IN===>333")
		returnedObj := asyncResult.GetReturnedObj()
		if returnedObj == nil {
			zlog.Debug("The asynchronous result has not been set when registering the callback function.")
			return
		}

		user := returnedObj.(*db_model.UserModel)

		userLoginRsp := &msg_struct.MsgLoginResponse{
			UserId:    user.UserId,
			UserName:  user.Name,
			ErrorCode: 0,
		}

		marshalData, marErr := json.Marshal(userLoginRsp)
		if marErr != nil {
			zlog.Error("LoginRouter marErr", marErr.Error())
			return
		}

		// Send response to the client
		conn := request.GetConnection()
		if sendErr := conn.SendMsg(1, marshalData); sendErr != nil {
			zlog.Error("LoginRouter sendErr", sendErr.Error())
			return
		}
		zlog.Debug("OnComplete OUT===>333")

		// Test actively throwing an exception (测试主动异常)
		/*
			a := 0
			b := 1
			c := b / a
			fmt.Println(c)
		*/
	})

	// Test: The original thread is blocked for 3 seconds, and the callback function is executed in the original thread,
	//       so it will be executed after 3 seconds
	// 测试:原来所属的线程阻塞3秒,回调函数因为是回到原来所属的线程里执行的,所以一定在3秒后执行.
	time.Sleep(time.Second * 3)

	zlog.Debug("AsyncOpRouter Handle OUT ===>111")
}


================================================
FILE: examples/zinx_async_op/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/examples/zinx_async_op/router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

func OnConnectionAdd(conn ziface.IConnection) {
	zlog.Debug("zinx_async_op OnConnectionAdd ===>")
}

func OnConnectionLost(conn ziface.IConnection) {
	zlog.Debug("zinx_async_op OnConnectionLost ===>")
}

func main() {
	s := znet.NewServer()

	s.SetOnConnStart(OnConnectionAdd)
	s.SetOnConnStop(OnConnectionLost)

	s.AddRouter(1, &router.LoginRouter{})

	s.Serve()
}


================================================
FILE: examples/zinx_client/Makefile
================================================
PROJECT_NAME:=zinx_client
VERSION:=v1


.PHONY: image run build clean

build:
	bash build.sh ${PROJECT_NAME}

image:
	docker build -t ${PROJECT_NAME}:${VERSION} .

run:
	docker run  -itd \
	-p 8999:8999 \
	${PROJECT_NAME}:${VERSION}


clean:
	rm -rf ${PROJECT_NAME} 



================================================
FILE: examples/zinx_client/build.sh
================================================
#!/bin/bash

set -e

APP_NAME=$1
APP_VERSION=v$(cat version)
BUILD_VERSION=$(git log -1 --oneline)
BUILD_TIME=$(date "+%FT%T%z")
GIT_REVISION=$(git rev-parse --short HEAD)
GIT_BRANCH=$(git name-rev --name-only HEAD)
GO_VERSION=$(go version)


go build -ldflags " \
	-X 'main.AppName=${APP_NAME}' 			\
	-X 'main.AppVersion=${APP_VERSION}'     \
	-X 'main.BuildVersion=${BUILD_VERSION//\'/_}' \
	-X 'main.BuildTime=${BUILD_TIME}'       \
	-X 'main.GitRevision=${GIT_REVISION}'   \
	-X 'main.GitBranch=${GIT_BRANCH}'       \
	-X 'main.GoVersion=${GO_VERSION}'       \
	" -o $APP_NAME


================================================
FILE: examples/zinx_client/c_router/hello.go
================================================
package c_router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type HelloRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloRouter) Handle(request ziface.IRequest) {
	zlog.Debug("Call HelloZinxRouter Handle")

	zlog.Debug("recv from server : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}


================================================
FILE: examples/zinx_client/c_router/ping.go
================================================
package c_router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// Ping test custom routing.
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	zlog.Debug("Call PingRouter Handle")
	zlog.Debug("recv from server : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	if err := request.GetConnection().SendBuffMsg(1, []byte("Hello[from client]")); err != nil {
		zlog.Error(err)
	}
}


================================================
FILE: examples/zinx_client/main.go
================================================
/**
* @Author: Aceld
* @Date: 2023/03/02
* @Mail: danbing.at@gmail.com
*    zinx client demo
 */
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

// Custom business logic of the client (客户端自定义业务)
func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(100, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

// Function to execute when the connection is created (创建连接的时候执行)
func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	// Set two connection properties after the connection is created (设置两个连接属性,在连接创建之后)
	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

// Function to execute when the connection is lost (连接断开的时候执行)
func DoClientConnectedLost(conn ziface.IConnection) {
	// Get the Name and Home properties of the connection before it is destroyed
	// (在连接销毁之前,查询conn的Name,Home属性)
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Debug("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Debug("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	// Create a client handle using Zinx's Method (创建一个Client句柄,使用Zinx的方法)
	client := znet.NewClient("127.0.0.1", 8999)

	// Set the business logic to execute when the connection is created or lost
	// (添加首次建立连接时的业务)
	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	// Register routers for the messages received from the server
	// (注册收到服务器消息业务路由)
	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	// Start the client
	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_client/version
================================================
v 1.0.0


================================================
FILE: examples/zinx_client_old/Makefile
================================================
PROJECT_NAME:=zinx_client
VERSION:=v1


.PHONY: image run build clean

build:
	bash build.sh ${PROJECT_NAME}

image:
	docker build -t ${PROJECT_NAME}:${VERSION} .

run:
	docker run  -itd \
	-p 8999:8999 \
	${PROJECT_NAME}:${VERSION}


clean:
	rm -rf ${PROJECT_NAME} 



================================================
FILE: examples/zinx_client_old/build.sh
================================================
#!/bin/bash

set -e

APP_NAME=$1
APP_VERSION=v$(cat version)
BUILD_VERSION=$(git log -1 --oneline)
BUILD_TIME=$(date "+%FT%T%z")
GIT_REVISION=$(git rev-parse --short HEAD)
GIT_BRANCH=$(git name-rev --name-only HEAD)
GO_VERSION=$(go version)


go build -ldflags " \
	-X 'main.AppName=${APP_NAME}' 			\
	-X 'main.AppVersion=${APP_VERSION}'     \
	-X 'main.BuildVersion=${BUILD_VERSION//\'/_}' \
	-X 'main.BuildTime=${BUILD_TIME}'       \
	-X 'main.GitRevision=${GIT_REVISION}'   \
	-X 'main.GitBranch=${GIT_BRANCH}'       \
	-X 'main.GoVersion=${GO_VERSION}'       \
	" -o $APP_NAME


================================================
FILE: examples/zinx_client_old/c_router/hello.go
================================================
package c_router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type HelloRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloRouter) Handle(request ziface.IRequest) {
	zlog.Debug("Call HelloZinxRouter Handle")
	zlog.Debug("recv from server : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

}


================================================
FILE: examples/zinx_client_old/c_router/ping.go
================================================
package c_router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	zlog.Debug("Call PingRouter Handle")

	zlog.Debug("recv from server : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	if err := request.GetConnection().SendBuffMsg(1, []byte("Hello[from client]")); err != nil {
		zlog.Error(err)
	}
}


================================================
FILE: examples/zinx_client_old/main.go
================================================
/**
* @Author: Aceld
* @Date: 2023/03/02
* @Mail: danbing.at@gmail.com
*    zinx client demo
 */
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:8999")
	if err != nil {
		fmt.Println("client start err, exit!", err)
		return
	}

	for {
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(100, []byte("ZinxPing")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData)
		if err != nil {
			fmt.Println("read head error")
			break
		}

		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Test Router:[Ping] Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_client_old/version
================================================
v 1.0.0


================================================
FILE: examples/zinx_closecallback/client/client.go
================================================
package main

import (
	"fmt"
	"os"
	"os/signal"
	"time"

	"github.com/aceld/zinx/examples/zinx_closecallback/router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// business handles the main business logic for sending ping messages
// business 处理发送ping消息的主要业务逻辑
func business(conn ziface.IConnection) {
	for i := 0; i < 3; i++ {
		err := conn.SendMsg(1, []byte(fmt.Sprintf("Ping %d", i+1)))
		if err != nil {
			fmt.Println("SendMsg error:", err)
			break
		}

		time.Sleep(1 * time.Second)
	}

	// Actively disconnect after sending is complete / 发送完成后主动断开连接
	fmt.Println("Client actively disconnects")
	conn.Stop()
}

// DoClientConnectedBegin is the callback function when connection starts
// DoClientConnectedBegin 是连接开始时的回调函数
func DoClientConnectedBegin(conn ziface.IConnection) {
	fmt.Println("Client connection started")

	// Set connection properties / 设置连接属性
	conn.SetProperty("StartTime", time.Now())

	// Add close callback function - record connection statistics / 添加关闭回调函数 - 记录连接统计
	conn.AddCloseCallback("stats", "connection-stats", func() {
		if startTime, err := conn.GetProperty("StartTime"); err == nil {
			duration := time.Since(startTime.(time.Time))
			fmt.Printf("Client connection duration: %v\n", duration)
		}
	})

	// Start business processing / 启动业务处理
	go business(conn)
}

// DoClientConnectedLost is the callback function when connection is lost
// DoClientConnectedLost 是连接断开时的回调函数
func DoClientConnectedLost(conn ziface.IConnection) {
	fmt.Println("Client connection lost")
}

func main() {
	// Create client / 创建客户端
	client := znet.NewClient("127.0.0.1", 8999)

	// Set connection start and stop callbacks / 设置连接开始和断开的回调
	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	// Add router / 添加路由
	client.AddRouter(0, &router.PingRouter{})

	// Start client / 启动客户端
	fmt.Println("Client starting")
	client.Start()

	// Wait for interrupt signal / 等待中断信号
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	<-c
}


================================================
FILE: examples/zinx_closecallback/router/ping_router.go
================================================
package router

import (
	"fmt"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// PingRouter handles ping messages
// PingRouter 处理ping消息
type PingRouter struct {
	znet.BaseRouter
}

// PreHandle processes the request before the main handler
// PreHandle 在主处理器之前处理请求
func (r *PingRouter) PreHandle(req ziface.IRequest) {
}

// Handle processes the main ping message and sends pong response
// Handle 处理主要的ping消息并发送pong响应
func (r *PingRouter) Handle(req ziface.IRequest) {
	// Reply to client / 回复客户端
	if err := req.GetConnection().SendMsg(0, []byte("Pong")); err != nil {
		fmt.Println("SendMsg error:", err)
	}
}

// PostHandle processes the request after the main handler
// PostHandle 在主处理器之后处理请求
func (r *PingRouter) PostHandle(req ziface.IRequest) {
}


================================================
FILE: examples/zinx_closecallback/server/server.go
================================================
package main

import (
	"fmt"
	"time"

	"github.com/aceld/zinx/examples/zinx_closecallback/router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// DoConnectionBegin is the callback function when connection starts
// DoConnectionBegin 是连接开始时的回调函数
func DoConnectionBegin(conn ziface.IConnection) {
	fmt.Println("Server connection started")

	// Set connection properties / 设置连接属性
	conn.SetProperty("StartTime", time.Now())

	// Add close callback function - cleanup resources / 添加关闭回调函数 - 清理资源
	conn.AddCloseCallback("cleanup", "resources", func() {
		fmt.Printf("Cleanup resources for connection %d\n", conn.GetConnID())
	})

	// Add close callback function - record statistics / 添加关闭回调函数 - 记录统计信息
	conn.AddCloseCallback("stats", "record", func() {
		if startTime, err := conn.GetProperty("StartTime"); err == nil {
			duration := time.Since(startTime.(time.Time))
			fmt.Printf("Connection %d duration: %v\n", conn.GetConnID(), duration)
		}
	})

	// Add close callback function - notify other components / 添加关闭回调函数 - 通知其他组件
	conn.AddCloseCallback("notification", "broadcast", func() {
		fmt.Printf("Notify other components: connection %d disconnected\n", conn.GetConnID())
	})
}

// DoConnectionLost is the callback function when connection is lost
// DoConnectionLost 是连接断开时的回调函数
func DoConnectionLost(conn ziface.IConnection) {
	fmt.Println("Server connection lost")
}

func main() {
	// Create server / 创建服务器
	s := znet.NewServer()

	// Set connection start and stop callbacks / 设置连接开始和断开的回调
	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	// Add router / 添加路由
	s.AddRouter(1, &router.PingRouter{})

	// Start server / 启动服务器
	fmt.Println("Server starting")
	s.Serve()
}


================================================
FILE: examples/zinx_decoder/README.MD
================================================
# LengthFieldFrameDecoder使用详解


>LengthFieldFrameDecoder是一个基于长度字段的解码器,比较难理解的解码器,它主要有5个核心的参数配置:

>maxFrameLength:     数据包最大长度

>lengthFieldOffset:  长度字段偏移量

>lengthFieldLength:  长度字段所占的字节数

>lengthAdjustment:   长度的调整值

>initialBytesToStrip:解码后跳过的字节数




## 示例讲解

#### TLV格式协议

TLV,即Tag(Type)—Length—Value,是一种简单实用的数据传输方案。在TLV的定义中,可以知道它包括三个域,分别为:标签域(Tag),长度域(Length),内容域(Value)。这里的长度域的值实际上就是内容域的长度。

```
解码前 (20 bytes)                                   解码后 (20 bytes)
+------------+------------+-----------------+      +------------+------------+-----------------+
|     Tag    |   Length   |     Value       |----->|     Tag    |   Length   |     Value       |
| 0x00000001 | 0x0000000C | "HELLO, WORLD"  |      | 0x00000001 | 0x0000000C | "HELLO, WORLD"  |
+------------+------------+-----------------+      +------------+------------+-----------------+
```
> Tag:   uint32类型,占4字节,Tag作为MsgId,暂定为1<br>
> Length:uint32类型,占4字节,Length标记Value长度12(hex:0x0000000C)<br>
> Value: 共12个字符,占12字节<br>

```
说明:
lengthFieldOffset   = 4            (Length的字节位索引下标是4) 长度字段的偏差
lengthFieldLength   = 4            (Length是4个byte) 长度字段占的字节数
lengthAdjustment    = 0            (Length只表示Value长度,程序只会读取Length个字节就结束,后面没有来,故为0,若Value后面还有crc占2字节的话,那么此处就是2。若Length标记的是Tag+Length+Value总长度,那么此处是-8)
initialBytesToStrip = 0            (这个0表示返回完整的协议内容Tag+Length+Value,如果只想返回Value内容,去掉Tag的4字节和Length的4字节,此处就是8) 从解码帧中第一次去除的字节数
maxFrameLength      = 2^32 + 4 + 4 (Length为uint类型,故2^32次方表示Value最大长度,此外Tag和Length各占4字节)
```


#### HTLV+CRC格式协议

HTLV+CRC,H头码,T功能码,L数据长度,V数据内容


```

+------+-------+---------+--------+--------+
| 头码  | 功能码 | 数据长度 | 数据内容 | CRC校验 |
| 1字节 | 1字节  | 1字节   | N字节   |  2字节  |
+------+-------+---------+--------+--------+

```

数据示例

```
头码   功能码 数据长度      Body                         CRC
A2      10     0E        0102030405060708091011121314 050B
```

```

说明:
   1.数据长度len是14(0E),这里的len仅仅指Body长度;

   lengthFieldOffset   = 2   (len的索引下标是2,下标从0开始) 长度字段的偏差
   lengthFieldLength   = 1   (len是1个byte) 长度字段占的字节数
   lengthAdjustment    = 2   (len只表示Body长度,程序只会读取len个字节就结束,但是CRC还有2byte没读呢,所以为2)
   initialBytesToStrip = 0   (这个0表示完整的协议内容,如果不想要A2,那么这里就是1) 从解码帧中第一次去除的字节数
   maxFrameLength      = 255 + 4(起始码、功能码、CRC) (len是1个byte,所以最大长度是无符号1个byte的最大值)
       
```


## 案例分析
以下7种案例足以满足所有协议,只处理断粘包,并不能处理错包,包的完整性需要依靠协议自身定义CRC来校验

#### 案例1:
```
lengthFieldOffset  =0 长度字段从0开始
lengthFieldLength  =2 长度字段本身占2个字节
lengthAdjustment   =0 需要调整0字节
initialBytesToStrip=0 解码后跳过0字节



解码前 (14 bytes)                 解码后 (14 bytes)
+--------+----------------+      +--------+----------------+
| Length | Actual Content |----->| Length | Actual Content |
| 0x000C | "HELLO, WORLD" |      | 0x000C | "HELLO, WORLD" |
+--------+----------------+      +--------+----------------+
```

> Length为0x000C,这个是十六进制,0x000C转化十进制就是14


#### 案例2:
```
lengthFieldOffset  =0 长度字段从0开始
lengthFieldLength  =2 长度字段本身占2个字节
lengthAdjustment   =0 需要调整0字节
initialBytesToStrip=2 解码后跳过2字节

解码前 (14 bytes)                 解码后 (12 bytes)
+--------+----------------+      +----------------+
| Length | Actual Content |----->| Actual Content |
| 0x000C | "HELLO, WORLD" |      | "HELLO, WORLD" |
+--------+----------------+      +----------------+
```
>这时initialBytesToStrip字段起作用了,在解码后会将前面的2字节跳过,所以解码后就只剩余了数据部分。

#### 案例3:
```
lengthFieldOffset  =0 长度字段从0开始
lengthFieldLength  =2 长度字段本身占2个字节
lengthAdjustment   =-2 需要调整 -2 字节
initialBytesToStrip=0 解码后跳过2字节


解码前 (14 bytes)                 解码后 (14 bytes)
+--------+----------------+      +--------+----------------+
| Length | Actual Content |----->| Length | Actual Content |
| 0x000E | "HELLO, WORLD" |      | 0x000E | "HELLO, WORLD" |
+--------+----------------+      +--------+----------------+
```

>这时lengthAdjustment起作用了,因为长度字段的值包含了长度字段本身的2字节,
如果要获取数据的字节数,需要加上lengthAdjustment的值,就是 14+(-2)=12,这样才算出来数据的长度。


#### 案例4:

```
lengthFieldOffset  =2 长度字段从第2个字节开始
lengthFieldLength  =3 长度字段本身占3个字节
lengthAdjustment   =0 需要调整0字节
initialBytesToStrip=0 解码后跳过0字节


解码前 (17 bytes)                              解码后 (17 bytes)
+----------+----------+----------------+      +----------+----------+----------------+
| Header 1 |  Length  | Actual Content |----->| Header 1 |  Length  | Actual Content |
|  0xCAFE  | 0x00000C | "HELLO, WORLD" |      |  0xCAFE  | 0x00000C | "HELLO, WORLD" |
+----------+----------+----------------+      +----------+----------+----------------+
```
>由于数据包最前面加了2个字节的Header,所以lengthFieldOffset为2,
说明长度字段是从第2个字节开始的。然后lengthFieldLength为3,说明长度字段本身占了3个字节。


#### 案例5:
```
lengthFieldOffset  =0 长度字段从第0个字节开始
lengthFieldLength  =3 长度字段本身占3个字节
lengthAdjustment   =2 需要调整2字节
initialBytesToStrip=0 解码后跳过0字节


解码前 (17 bytes)                              解码后 (17 bytes)
+----------+----------+----------------+      +----------+----------+----------------+
|  Length  | Header 1 | Actual Content |----->|  Length  | Header 1 | Actual Content |
| 0x00000C |  0xCAFE  | "HELLO, WORLD" |      | 0x00000C |  0xCAFE  | "HELLO, WORLD" |
+----------+----------+----------------+      +----------+----------+----------------+
```
>lengthFieldOffset为0,所以长度字段从0字节开始。lengthFieldLength为3,长度总共占3字节。
因为长度字段后面还剩余14字节的总数据,但是长度字段的值为12,只表示了数据的长度,不包含头的长度,
所以lengthAdjustment为2,就是12+2=14,计算出Header+Content的总长度。


#### 案例6:

```
lengthFieldOffset  =1 长度字段从第1个字节开始
lengthFieldLength  =2 长度字段本身占2个字节
lengthAdjustment   =1 需要调整1字节
initialBytesToStrip=3 解码后跳过3字节

解码前 (16 bytes)                               解码后 (13 bytes)
+------+--------+------+----------------+      +------+----------------+
| HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
| 0xCA | 0x000C | 0xFE | "HELLO, WORLD" |      | 0xFE | "HELLO, WORLD" |
+------+--------+------+----------------+      +------+----------------+
```
>这一次将Header分为了两个1字节的部分,lengthFieldOffset为1表示长度从第1个字节开始,lengthFieldLength为2表示长度字段占2个字节。
因为长度字段的值为12,只表示了数据的长度,所以lengthAdjustment为1,12+1=13,
表示Header的第二部分加上数据的总长度为13。因为initialBytesToStrip为3,所以解码后跳过前3个字节。


#### 案例7:
```
lengthFieldOffset  =1 长度字段从第1个字节开始
lengthFieldLength  =2 长度字段本身占2个字节
lengthAdjustment   =-3 需要调整 -3 字节
initialBytesToStrip=3 解码后跳过3字节

解码前 (16 bytes)                               解码后 (13 bytes)
+------+--------+------+----------------+      +------+----------------+
| HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
| 0xCA | 0x0010 | 0xFE | "HELLO, WORLD" |      | 0xFE | "HELLO, WORLD" |
+------+--------+------+----------------+      +------+----------------+
```
>这一次长度字段的值为16,表示包的总长度,所以lengthAdjustment为 -3 ,16+ (-3)=13,
表示Header的第二部分加数据部分的总长度为13字节。initialBytesToStrip为3,解码后跳过前3个字节。



================================================
FILE: examples/zinx_decoder/bili/README.MD
================================================
# 一款水机设备服务端模拟程序


```shell
HTLV+CRC,H头码,T功能码,L数据长度,V数据内容
+------+-------+---------+--------+--------+
| 头码  | 功能码 | 数据长度 | 数据内容 | CRC校验 |
| 1字节 | 1字节  | 1字节   | N字节   |  2字节  |
+------+-------+---------+--------+--------+

头码   功能码 数据长度      Body                         CRC
A2    10    0E           0102030405060708091011121314 050B


说明:
  1.数据长度len是14(0E),这里的len仅仅指Body长度;
   
   lengthFieldOffset   = 2   (len的索引下标是2,下标从0开始) 长度字段的偏差
   lengthFieldLength   = 1   (len是1个byte) 长度字段占的字节数
   lengthAdjustment    = 2   (len只表示Body长度,程序只会读取len个字节就结束,但是CRC还有2byte没读呢,所以为2)
   initialBytesToStrip = 0   (这个0表示完整的协议内容,如果不想要A2,那么这里就是1) 从解码帧中第一次去除的字节数
   maxFrameLength      = 255 + 4(起始码、功能码、CRC) (len是1个byte,所以最大长度是无符号1个byte的最大值)
```


================================================
FILE: examples/zinx_decoder/bili/main.go
================================================
package main

import (
	"github.com/aceld/zinx/examples/zinx_decoder/bili/router"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

func DoConnectionBegin(conn ziface.IConnection) {
}

func DoConnectionLost(conn ziface.IConnection) {
}

func main() {
	server := znet.NewServer(func(s *znet.Server) {
		s.Port = 9090
		/*
			s.LengthField = ziface.LengthField{
				MaxFrameLength:      math.MaxUint8 + 4,
				LengthFieldOffset:   2,
				LengthFieldLength:   1,
				LengthAdjustment:    2,
				InitialBytesToStrip: 0,
			}
		*/
	})
	server.SetOnConnStart(DoConnectionBegin)
	server.SetOnConnStop(DoConnectionLost)
	server.AddInterceptor(zdecoder.NewHTLVCRCDecoder())
	server.AddRouter(0x10, &router.Data0x10Router{})
	server.AddRouter(0x13, &router.Data0x13Router{})
	server.AddRouter(0x14, &router.Data0x14Router{})
	server.AddRouter(0x15, &router.Data0x15Router{})
	server.AddRouter(0x16, &router.Data0x16Router{})
	server.Serve()
}


================================================
FILE: examples/zinx_decoder/bili/router/bili0x10router.go
================================================
package router

import (
	"bytes"
	"encoding/hex"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type Data0x10Router struct {
	znet.BaseRouter
}

func (this *Data0x10Router) Handle(request ziface.IRequest) {
	zlog.Ins().DebugF("Data0x10Router Handle %s \n", hex.EncodeToString(request.GetMessage().GetData()))
	_response := request.GetResponse()
	if _response != nil {
		switch _response.(type) {
		case zdecoder.HtlvCrcDecoder:
			_data := _response.(zdecoder.HtlvCrcDecoder)
			//zlog.Ins().DebugF("Data0x10Router %v \n", _data)
			buffer := pack10(_data)
			request.GetConnection().Send(buffer)
		}
	}
}

// 头码   功能码 数据长度      Body                         CRC
// A2      10     0E        0102030405060708091011121314 050B
// HeadCode FuncCode DataLen   Body                         CRC
// A2       10       0E        0102030405060708091011121314 050B
func pack10(_data zdecoder.HtlvCrcDecoder) []byte {
	buffer := bytes.NewBuffer([]byte{})
	buffer.WriteByte(0xA1)
	buffer.WriteByte(_data.Funcode)
	buffer.WriteByte(0x1E)
	//3~9:唯一设备码	将IMEI码转换为16进制
	//3~9: Unique device code: Convert the IMEI code to hexadecimal
	buffer.Write(_data.Body[:7])
	//10~14:园区代码	后台根据幼儿园生成的唯一代码
	//10~14: Park code: A unique code generated by the background according to the kindergarten
	buffer.Write([]byte{10, 11, 12, 13, 14})
	//15~18:时间戳	实际当前北京时间的时间戳,转换为16进制
	//15~18: Timestamp: The actual current Beijing time stamp, converted to hexadecimal
	buffer.Write([]byte{15, 16, 17, 18})
	//19:RFID模块工作模式	0x01-离线工作模式(默认工作模式)0x02-在线工作模式
	//19: RFID module working mode: 0x01-offline working mode (default working mode) 0x02-online working mode
	buffer.WriteByte(0x02)
	//20~27:通讯密匙	预留,全填0x00
	//20~27: Communication key: Reserved, fill with 0x00
	buffer.Write([]byte{20, 21, 22, 23, 24, 25, 26, 27})
	//28:出水方式	0x00-放杯出水,取杯停止出水 0x01-刷一下卡出水,再刷停止出水【数联默认】
	//28: Water outlet mode: 0x00-put cup and stop water, 0x01-swipe card for water, swipe card again to stop water [Suliandu default]
	buffer.WriteByte(0x01)
	//29~32:预留	全填0x00
	//29~32: Reserved: Fill with 0x00
	buffer.Write([]byte{29, 30, 31, 32})
	crc := zdecoder.GetCrC(buffer.Bytes())
	buffer.Write(crc)
	return buffer.Bytes()

}


================================================
FILE: examples/zinx_decoder/bili/router/bili0x13router.go
================================================
package router

import (
	"bytes"
	"fmt"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

type Data0x13Router struct {
	znet.BaseRouter
}

func (this *Data0x13Router) Handle(request ziface.IRequest) {
	fmt.Println("Data0x13Router Handle", request.GetMessage().GetData())
	_response := request.GetResponse()
	if _response != nil {
		switch _response.(type) {
		case zdecoder.HtlvCrcDecoder:
			_data := _response.(zdecoder.HtlvCrcDecoder)
			fmt.Println("Data0x13Router", _data)
			buffer := pack13(_data)
			request.GetConnection().Send(buffer)
		}
	}
}

// 头码   功能码 数据长度       Body                         CRC
// A2      10     0E         0102030405060708091011121314 050B
// HeadCode FuncCode DataLen Body                         CRC
// A2       10       0E      0102030405060708091011121314 050B
func pack13(_data zdecoder.HtlvCrcDecoder) []byte {
	buffer := bytes.NewBuffer([]byte{})
	buffer.WriteByte(0xA1)
	buffer.WriteByte(_data.Funcode)
	buffer.WriteByte(0x0E)
	//3~9:3~6:用户卡号	用户IC卡卡号
	//3~9:3~6: User card number: User IC card number
	buffer.Write(_data.Body[:4])
	//7:卡状态:	0x00-未绑定(如服务器未查询到该IC卡时)
	//0x01-已绑定
	//0x02-解除绑定(如服务器查询到该IC卡解除绑定时下发)
	//7: Card Status: 0x00-Unbound (when the card is not found in the server)
	//0x01-Bound
	//0x02-Unbound (when the server sends a command to unbind the card)
	buffer.WriteByte(0x01)
	//8~9:剩余使用天数	该用户的剩余流量天数
	//8~9: Remaining usage days: the remaining number of days of usage for the user's data plan.
	buffer.Write([]byte{8, 9})
	//10~11:每次最大出水量	单位mL,实际出水量
	//10~11: Maximum dispensing amount per use, unit: mL, actual dispensing amount.
	buffer.Write([]byte{10, 11})
	//12~16:预留	全填0x00
	//12~16: Reserved, all filled with 0x00.
	buffer.Write([]byte{12, 13, 14, 15, 16})
	crc := zdecoder.GetCrC(buffer.Bytes())
	buffer.Write(crc)
	return buffer.Bytes()

}


================================================
FILE: examples/zinx_decoder/bili/router/bili0x14router.go
================================================
package router

import (
	"bytes"
	"fmt"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

type Data0x14Router struct {
	znet.BaseRouter
}

func (this *Data0x14Router) Handle(request ziface.IRequest) {
	fmt.Println("Data0x14Router Handle", request.GetMessage().GetData())
	_response := request.GetResponse()
	if _response != nil {
		switch _response.(type) {
		case zdecoder.HtlvCrcDecoder:
			_data := _response.(zdecoder.HtlvCrcDecoder)
			fmt.Println("Data0x14Router", _data)
			buffer := pack14(_data)
			request.GetConnection().Send(buffer)
		}
	}
}

// 头码   功能码 数据长度       Body                         CRC
// A2      10     0E         0102030405060708091011121314 050B
// HeadCode FuncCode DataLen Body                         CRC
// A2       10       0E      0102030405060708091011121314 050B
func pack14(_data zdecoder.HtlvCrcDecoder) []byte {
	_data.Data[0] = 0xA1
	buffer := bytes.NewBuffer(_data.Data[:len(_data.Data)-2])
	crc := zdecoder.GetCrC(buffer.Bytes())
	buffer.Write(crc)
	return buffer.Bytes()

}


================================================
FILE: examples/zinx_decoder/bili/router/bili0x15router.go
================================================
package router

import (
	"bytes"
	"fmt"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

type Data0x15Router struct {
	znet.BaseRouter
}

func (this *Data0x15Router) Handle(request ziface.IRequest) {
	fmt.Println("Data0x15Router Handle", request.GetMessage().GetData())
	_response := request.GetResponse()
	if _response != nil {
		switch _response.(type) {
		case zdecoder.HtlvCrcDecoder:
			_data := _response.(zdecoder.HtlvCrcDecoder)
			fmt.Println("Data0x15Router", _data)
			buffer := pack15(_data)
			request.GetConnection().Send(buffer)
		}
	}
}

// 头码   功能码 数据长度      Body                         CRC
// A2      10     0E        0102030405060708091011121314 050B
// HeaderCode FunctionCode DataLength Body                         CRC
// A2         10           0E         0102030405060708091011121314 050B
func pack15(_data zdecoder.HtlvCrcDecoder) []byte {
	buffer := bytes.NewBuffer([]byte{})
	buffer.WriteByte(0xA1)
	buffer.WriteByte(_data.Funcode)
	buffer.WriteByte(0x26)
	//3~9: Device Code Convert IMEI code to hex (3~9:设备代码, 将IMEI码转换为16进制)
	buffer.Write(_data.Body[:7])
	//10: Model Code A8 (Hot Type Kindergarten Machine) , 10: 机型代码	A8(即热式幼儿园机)
	buffer.WriteByte(0xA8)
	//11:主机状态1
	//Bit0:0-待机中,1-运行中
	//Bit1:0-非智控,1-智控【本设备按智控】
	//Bit2:0-不能饮用,1-可以饮用
	//Bit3:0-无人用水,1-有人用水
	//Bit4:0-上电进水中,1-正常工作中
	//Bit5:0-消毒未启动,1-消毒进行中
	//Bit6:0-低压开关断开(无水),1-低压开关接通(有水)
	//Bit7:0-主机不带RO,1-主机带RO
	// 11: Host Status 1
	// Bit0: 0-Standby, 1-Running
	// Bit1: 0-Non-intelligent control, 1-Intelligent control [This device follows intelligent control]
	// Bit2: 0-Cannot be drunk, 1-Can be drunk
	// Bit3: 0-No one uses water, 1-Someone uses water
	// Bit4: 0-Entering water at power-on, 1-Working normally
	// Bit5: 0-Disinfection not started, 1-Disinfection in progress
	// Bit6: 0-Low voltage switch off (no water), 1-Low voltage switch on (with water)
	// Bit7: 0-Master without RO, 1-Master with RO
	buffer.WriteByte(0x01)
	//12:主机状态2	Bit0:0-RO机不允许启动水泵,1-RO机允许启动水泵
	//Bit1:0-开水无人用,1-开水有人用
	//Bit2:0-高压开关断开(满水),1-高压开关接通(缺水)
	//Bit3:0-冰水无人用,1-冰水有人用【本设备无意义】
	//Bit4:0-无漏水信号,1-有漏水信号
	//Bit5:0-紫外灯未启动,1-紫外线灯杀菌中
	//Bit6:预留
	//Bit7:预留
	// 12: Host Status 2
	// Bit0: 0-RO machine does not allow pump to start, 1-RO machine allows pump to start
	// Bit1: 0-No one uses hot water, 1-Someone uses hot water
	// Bit2: 0-High-voltage switch off (full water), 1-High-voltage switch on (lack of water)
	// Bit3: 0-No one uses ice water, 1-Someone uses ice water [meaningless for this device]
	// Bit4: 0-No water leakage signal, 1-Water leakage signal
	// Bit5: 0-Ultraviolet lamp not started, 1-Ultraviolet lamp sterilizing
	// Bit6: Reserved
	// Bit7: Reserved
	buffer.WriteByte(0x01)
	//13:水位状态
	//(即热水位)	Bit0:低水位,0-代表无水,1-代表有水【本设备低水位有水即表示水满】
	//Bit1:中水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit2:高水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit3:溢出水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit4:预留
	//Bit5:预留
	//Bit6:预留
	//Bit7:预留
	// 13: Water level status (i.e. hot water level)
	// Bit0: Low water level, 0-represents no water, 1-represents water [Low water level with water indicates full water for this device]
	// Bit1: Medium water level, 0-represents no water, 1-represents water [Meaningless for this device]
	// Bit2: High water level, 0-represents no water, 1-represents water [Meaningless for this device]
	// Bit3: Overflow water level, 0-represents no water, 1-represents water [Meaningless for this device]
	// Bit4: Reserved
	// Bit5: Reserved
	// Bit6: Reserved
	// Bit7: Reserved
	buffer.WriteByte(0x01)
	buffer.WriteByte(0x01)
	// 14: Hot water temperature 0℃100℃, indicating the current hot water temperature
	//14:开水温度	0℃~100℃,表示当前开水温度
	buffer.WriteByte(0x1A)
	// 15: Stop heating temperature of current system 30~98℃, actual value
	// 15:当前系统的停止加热温度	30~98℃,实际数值
	buffer.WriteByte(0x27)
	//16:负载状态
	//Bit0:加热,0-未加热,1-加热中
	//Bit1:进水,0-未进水,1-进水中
	//Bit2:换水或消毒,0-未换水,1-换水或消毒
	//Bit3:冲洗,0-未冲洗,1-冲洗中
	//Bit4:增压泵和RO进水阀,0-未启动,1-启动增压泵和RO进水阀
	//Bit5:RO进水阀2,0-未启动,1-启动中【本设备无意义】
	//Bit6:开水出水阀1,0-未启动,1-启动中
	//Bit7:净化水出水阀1,0-未启动,1-启动中【本设备无意义】
	// 16: Load status
	// Bit0: Heating, 0 - Not heating, 1 - Heating
	// Bit1: Inlet water, 0 - No inlet water, 1 - Inlet water
	// Bit2: Water change or disinfection, 0 - No change, 1 - Water change or disinfection
	// Bit3: Flushing, 0 - Not flushing, 1 - Flushing
	// Bit4: Booster pump and RO inlet valve, 0 - Not started, 1 - Started booster pump and RO inlet valve
	// Bit5: RO inlet valve 2, 0 - Not started, 1 - Started 【Irrelevant to this device】
	// Bit6: Hot water outlet valve 1, 0 - Not started, 1 - Started
	// Bit7: Purified water outlet valve 1, 0 - Not started, 1 - Started 【Irrelevant to this device】
	buffer.WriteByte(0x01)
	//17:负载状态2	预留,填0x00
	//17: Load State 2, reserved, fill with 0x00.
	buffer.WriteByte(0x00)
	//18:故障状态
	//Bit0:故障1,0-无故障,1-有故障
	//Bit1:故障2,0-无故障,1-有故障
	//Bit2:障保3,0-无故障,1-有故障
	//Bit3:故障4 ,0-无故障,1-有故障
	//Bit4:故障5 ,0-无故障,1-有故障
	//Bit5:故障6,0-无故障,1-有故障
	//Bit6:故障7,0-无故障,1-有故障
	//Bit7:故障8,0-无故障,1-有故障
	//18: Fault status
	//Bit0: Fault 1, 0-no fault, 1-fault
	//Bit1: Fault 2, 0-no fault, 1-fault
	//Bit2: Fault 3, 0-no fault, 1-fault
	//Bit3: Fault 4, 0-no fault, 1-fault
	//Bit4: Fault 5, 0-no fault, 1-fault
	//Bit5: Fault 6, 0-no fault, 1-fault
	//Bit6: Fault 7, 0-no fault, 1-fault
	//Bit7: Fault 8, 0-no fault, 1-fault
	buffer.WriteByte(0x00)
	//19:故障状态2
	//Bit0:故障A,0-无故障,1-有故障
	//Bit1:故障B,0-无故障,1-有故障
	//Bit2:障保C,0-无故障,1-有故障
	//Bit3:故障9,0-无故障,1-有故障
	//Bit4:故障D,0-无故障,1-有故障
	//Bit5:故障E,0-无故障,1-有故障
	//Bit6:预留
	//Bit7:预留
	//19: Fault status 2
	//Bit0: Fault A, 0 - no fault, 1 - there is a fault
	//Bit1: Fault B, 0 - no fault, 1 - there is a fault
	//Bit2: Fault C, 0 - no fault, 1 - there is a fault
	//Bit3: Fault 9, 0 - no fault, 1 - there is a fault
	//Bit4: Fault D, 0 - no fault, 1 - there is a fault
	//Bit5: Fault E, 0 - no fault, 1 - there is a fault
	//Bit6: Reserved
	//Bit7: Reserved
	buffer.WriteByte(0x00)
	//20:主板软件版本	实际数值1~255
	//20: Mainboard software version, actual value 1~255.
	buffer.WriteByte(0x01)
	//21:水位状态2
	//Bit0:纯水箱低水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit1:纯水箱中水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit2:纯水箱高水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit3:保温箱低水位,0-代表无水,1-代表有水
	//Bit4:保温箱中水位,0-代表无水,1-代表有水【本设备无意义】
	//Bit5:保温箱高水位,0-代表无水,1-代表有水
	//Bit6:保温箱溢水位,0-代表无水,1-代表有水
	//Bit7:预留
	//21: Water level status 2
	//Bit0: Low water level in pure water tank, 0 - no water, 1 - water present (not applicable for this device)
	//Bit1: Medium water level in pure water tank, 0 - no water, 1 - water present (not applicable for this device)
	//Bit2: High water level in pure water tank, 0 - no water, 1 - water present (not applicable for this device)
	//Bit3: Low water level in insulation box, 0 - no water, 1 - water present
	//Bit4: Medium water level in insulation box, 0 - no water, 1 - water present (not applicable for this device)
	//Bit5: High water level in insulation box, 0 - no water, 1 - water present
	//Bit6: Overflow water level in insulation box, 0 - no water, 1 - water present
	//Bit7: Reserved
	buffer.WriteByte(0x01)
	//22:温开水温度	0~100℃
	//22: Hot water temperature in Celsius degree, range from 0 to 100℃.
	buffer.WriteByte(0x30)
	//23~24:剩余滤芯寿命	单位:小时,实际数值
	//23~24: Remaining filter life, unit: hours, actual numerical value
	buffer.Write([]byte{23, 24})
	//25~26:剩余紫外线灯寿命
	//25~26: Remaining UV lamp life, measured in hours, actual numerical value.
	buffer.Write([]byte{25, 26})
	//27~28:源水TDS值	0x0000-无此功能 ,实际数值,单位,ppm
	//27~28: Source water TDS value, 0x0000 - no such function, actual value in ppm
	buffer.Write([]byte{27, 28})
	//29:净水TDS值	0x00-无此功能, 实际数值,单位,ppm
	//29: TDS value of purified water 0x00 - No such function, actual value, unit: ppm
	buffer.WriteByte(0x00)
	//30~33:耗电量	0xFFFFFFFF-无此功能, 实际数值,高位在前,低位在后,单位wh
	//30~33: Power consumption, 0xFFFFFFFF - not supported, actual value, high byte first, low byte last, unit is Wh.
	buffer.Write([]byte{30, 31, 32, 33})
	//34:信号强度	0x01~0x28
	//0x01~0x0A对应:-81~-90dbm=极差
	//0x0B~0x14对应:-71~-80dbm=差
	//0x15~0x1E对应-61~-70dbm=好
	//0x1F~0x28对应:-41以上~-50dbm=良好
	//34: Signal strength 0x01~0x28
	//0x010x0A correspond to -81~-90dbm=poor
	//0x0B0x14 correspond to -71-80dbm=weak
	//0x150x1E correspond to -61-70dbm=good
	//0x1F0x28 correspond to -41 and above-50dbm=excellent
	buffer.WriteByte(0x30)
	//35~40:预留	全填0x00
	//35~40: Reserved. All filled with 0x00.
	buffer.Write([]byte{0x00, 0x00})
	crc := zdecoder.GetCrC(buffer.Bytes())
	buffer.Write(crc)
	return buffer.Bytes()

}


================================================
FILE: examples/zinx_decoder/bili/router/bili0x16router.go
================================================
package router

import (
	"bytes"
	"fmt"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

type Data0x16Router struct {
	znet.BaseRouter
}

func (this *Data0x16Router) Handle(request ziface.IRequest) {
	fmt.Println("Data0x16Router Handle", request.GetMessage().GetData())
	_response := request.GetResponse()
	if _response != nil {
		switch _response.(type) {
		case zdecoder.HtlvCrcDecoder:
			_data := _response.(zdecoder.HtlvCrcDecoder)
			fmt.Println("Data0x16Router", _data)
			buffer := pack16(_data)
			request.GetConnection().Send(buffer)
		}
	}
}

// Pack a complete 0x16 protocol data
// Format:
// HeadCode FuncCode DataLen Body                         CRC
// A2       10       0E      0102030405060708091011121314 050B
// 头码      功能码    数据长度  Body                         CRC
// A2       10        0E     0102030405060708091011121314 050B
func pack16(_data zdecoder.HtlvCrcDecoder) []byte {
	_data.Data[0] = 0xA1
	buffer := bytes.NewBuffer(_data.Data[:len(_data.Data)-2])
	crc := zdecoder.GetCrC(buffer.Bytes())
	buffer.Write(crc)
	return buffer.Bytes()

}


================================================
FILE: examples/zinx_decoder/client/client.go
================================================
package main

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"os"
	"os/signal"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// Use this method to generate mock data. (使用该方法生成模拟数据)
func getTLVPackData() []byte {
	msgID := 1
	tag := make([]byte, 4)
	binary.BigEndian.PutUint32(tag, uint32(msgID))

	str := "HELLO, WORLD"
	var value = []byte(str)

	length := make([]byte, 4)
	binary.BigEndian.PutUint32(length, uint32(len(value)))

	_data := make([]byte, 0)
	_data = append(_data, tag...)
	_data = append(_data, length...)
	_data = append(_data, value...)
	fmt.Println("--->", len(_data), hex.EncodeToString(_data))
	return _data
}

func getTLVData(index int) []byte {
	// Get a complete TLV simulated data package by using the getTLVPackData() method: 000000010000000c48454c4c4f2c20574f524c44.
	// (通过 getTLVPackData()方法,获得一段完整的TLV模拟数据包:000000010000000c48454c4c4f2c20574f524c44)
	tlvPackData := []string{
		"000000010000000c48454c4c4f2c20574f524c44000000010000000c",                         //one and a half packets(一包半)
		"48454c4c4f2c20574f524c44",                                                         //the remaining half of the packet(剩下的半包)
		"000000010000000c48454c4c4f2c20574f524c44000000010000000c48454c4c4f2c20574f524c44", //two packets(两包)
	}

	// The simulation sequence here is: two complete packages, one half package, and the remaining half package.
	// (此处模拟顺序如:两包一包半剩下的半包)
	index = index % 3
	if index == 0 {
		fmt.Println("Simulation-Data - Sticking (粘包)")
		index = 2 //Simulate a situation of packet sticking, where two packets of data are combined together. (模拟粘包情况,两包数据一起)
	} else {
		// Simulate the situation of message fragmentation, with one and a half packages and the remaining half package
		// (模拟断包情况,一包半+剩下的半包)
		index = index / 2 % 2
		fmt.Println("Simulation-Data - Fragmentation(断包)")
	}
	arr, _ := hex.DecodeString(tlvPackData[index])
	return arr
}

func getHTLVCRCData(index int) []byte {
	// A complete HTLVCRC simulation data packet: A2100E0102030405060708091011121314050B
	// (一段完整的HTLVCRC模拟数据包:A2100E0102030405060708091011121314050B)
	tlvPackData := []string{
		"a21018686574000004d30000000000000000000000000000000000e7a2a2130e686574000004d300000001", //one and a half packets(一包半)
		"00000040c3", //剩下的半包
		"a21018686574000004d30000000000000000000000000000000000e7a2a2130e686574000004d30000000100000040c3", //two packets(两包)
	}

	// Simulated sequence here: two complete packages, one half package, and the remaining half package.
	// (此处模拟顺序如:两包一包半剩下的半包)
	index = index % 3
	if index == 0 {
		fmt.Println("Simulation-Data - Sticking (粘包)")
		index = 2 //Simulate a situation of packet sticking, where two packets of data are combined together. (模拟粘包情况,两包数据一起)
	} else {
		// Simulate the situation of message fragmentation, with one and a half packages and the remaining half package
		// (模拟断包情况,一包半+剩下的半包)
		index = index / 2 % 2
		fmt.Println("Simulation-Data - Fragmentation(断包)")
	}
	arr, _ := hex.DecodeString(tlvPackData[index])
	return arr
}

func business(conn ziface.IConnection) {
	var i int
	for {
		//buffer := getTLVData(i)
		buffer := getHTLVCRCData(i)
		conn.Send(buffer)
		i++
		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")
	go business(conn)
}

func main() {

	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(DoClientConnectedBegin)

	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)

}


================================================
FILE: examples/zinx_decoder/router/htlvcrcbusinessrouter.go
================================================
package router

import (
	"encoding/hex"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type HtlvCrcBusinessRouter struct {
	znet.BaseRouter
}

func (this *HtlvCrcBusinessRouter) Handle(request ziface.IRequest) {

	//MsgID
	msgID := request.GetMessage().GetMsgID()
	zlog.Ins().DebugF("Call HtlvCrcBusinessRouter Handle %d %s\n", msgID, hex.EncodeToString(request.GetMessage().GetData()))

	resp := request.GetResponse()
	if resp == nil {
		return
	}

	tlvData := resp.(zdecoder.HtlvCrcDecoder)

	zlog.Ins().DebugF("do msgid=0x10 data business %+v\n", tlvData)
}


================================================
FILE: examples/zinx_decoder/router/tlvbusinessrouter.go
================================================
package router

import (
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type TLVBusinessRouter struct {
	znet.BaseRouter
}

func (this *TLVBusinessRouter) Handle(request ziface.IRequest) {

	msgID := request.GetMessage().GetMsgID()
	zlog.Ins().DebugF("Call TLVRouter Handle %d %+v\n", msgID, request.GetMessage().GetData())

	resp := request.GetResponse()
	if resp == nil {
		return
	}

	tlvData := resp.(zdecoder.TLVDecoder)
	zlog.Ins().DebugF("do msgid=0x00000001 data business %+v\n", tlvData)
}


================================================
FILE: examples/zinx_decoder/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/examples/zinx_decoder/router"
	"github.com/aceld/zinx/zdecoder"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

func DoConnectionBegin(conn ziface.IConnection) {
	zlog.Ins().InfoF("DoConnectionBegin is Called ...")
}

func DoConnectionLost(conn ziface.IConnection) {
	zlog.Ins().InfoF("Conn is Lost")
}

func main() {
	//zlog.SetLogFile("./logs", "app.log")
	s := znet.NewServer()

	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	// TLV protocol corresponding to business function
	// TLV协议对应业务功能
	s.AddRouter(0x00000001, &router.TLVBusinessRouter{})

	// Process HTLVCRC protocol data
	// 处理HTLVCRC协议数据
	s.SetDecoder(zdecoder.NewHTLVCRCDecoder())

	// TLV protocol corresponding to business function, because the funcode field in client.go is 0x10
	// TLV协议对应业务功能,因为client.go中模拟数据funcode字段为0x10
	s.AddRouter(0x10, &router.HtlvCrcBusinessRouter{})

	// TLV protocol corresponding to business function, because the funcode field in client.go is 0x13
	// TLV协议对应业务功能,因为client.go中模拟数据funcode字段为0x13
	s.AddRouter(0x13, &router.HtlvCrcBusinessRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_dynamic_bind/client/client.go
================================================
package main

import (
	"os"
	"os/signal"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

const (
	PingType = 1
	PongType = 2
)

// ping response router
type PongRouter struct {
	znet.BaseRouter
	client string
}

// Hash 工作模式下,需要等待接受到client1的pong后,才会收到client2和client3的pong
// DynamicBind工作模式下,client2, client3 都会立马收到pong, 但client1的pong会被阻塞十秒后才收到
func (p *PongRouter) Handle(request ziface.IRequest) {
	//read server pong data
	zlog.Infof("---------client:%s, recv from server:%s, msgId=%d, data=%s ----------\n",
		p.client, request.GetConnection().RemoteAddr(), request.GetMsgID(), string(request.GetData()))
}

func onClient1Start(conn ziface.IConnection) {
	zlog.Infof("client1 connection start, %s->%s\n", conn.LocalAddrString(), conn.RemoteAddrString())
	//send ping
	err := conn.SendMsg(PingType, []byte("Ping From Client1"))
	if err != nil {
		zlog.Error(err)
	}
}

func onClient2Start(conn ziface.IConnection) {
	zlog.Infof("client2 connection start, %s->%s\n", conn.LocalAddrString(), conn.RemoteAddrString())
	//send ping
	err := conn.SendMsg(PingType, []byte("Ping From Client2"))
	if err != nil {
		zlog.Error(err)
	}
}

func onClient3Start(conn ziface.IConnection) {
	zlog.Infof("client3 connection start, %s->%s\n", conn.LocalAddrString(), conn.RemoteAddrString())
	//send ping
	err := conn.SendMsg(PingType, []byte("Ping From Client3"))
	if err != nil {
		zlog.Error(err)
	}
}

func main() {
	//Create a client client
	client1 := znet.NewClient("127.0.0.1", 8999)
	client1.SetOnConnStart(onClient1Start)
	client1.AddRouter(PongType, &PongRouter{client: "client1"})
	client1.Start()

	time.Sleep(time.Second)

	client2 := znet.NewClient("127.0.0.1", 8999)
	client2.SetOnConnStart(onClient2Start)
	client2.AddRouter(PongType, &PongRouter{client: "client2"})
	client2.Start()

	time.Sleep(time.Second)

	client3 := znet.NewClient("127.0.0.1", 8999)
	client3.SetOnConnStart(onClient3Start)
	client3.AddRouter(PongType, &PongRouter{client: "client3"})
	client3.Start()

	//Prevent the process from exiting, waiting for an interrupt signal
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)
	<-signalChan
	client1.Stop()
	client2.Stop()
	client3.Stop()

	time.Sleep(time.Second)
}


================================================
FILE: examples/zinx_dynamic_bind/server/conf/zinx.json
================================================
{
    "Name":"zinx server DynamicBind Mode Demo",
    "Host":"127.0.0.1",
    "TCPPort":8999,
    "MaxConn":12000,
    "WorkerPoolSize":1,
    "MaxWorkerTaskLen":50,
    "WorkerMode":"DynamicBind"
  }

================================================
FILE: examples/zinx_dynamic_bind/server/server.go
================================================
package main

import (
	"sync/atomic"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

func OnConnectionAdd(conn ziface.IConnection) {
	zlog.Debug("OnConnectionAdd:", conn.GetConnection().RemoteAddr())
}

func OnConnectionLost(conn ziface.IConnection) {
	zlog.Debug("OnConnectionLost:", conn.GetConnection().RemoteAddr())
}

type blockRouter struct {
	znet.BaseRouter
}

var Block = int32(1)

// 模拟阻塞操作
func (r *blockRouter) Handle(request ziface.IRequest) {
	//read client data
	zlog.Infof("recv from client:%s, msgId=%d, data=%s\n", request.GetConnection().RemoteAddr(), request.GetMsgID(), string(request.GetData()))

	// 第一次处理时,模拟任务阻塞操作, Hash 模式下,后面的连接的任务得不到处理
	// DynamicBind 模式下,看后面的连接的任务会得到即使处理,不会因为前面连接的任务阻塞而得不到处理
	// 这里只模拟一次阻塞操作。
	if atomic.CompareAndSwapInt32(&Block, 1, 0) {
		zlog.Infof("blockRouter handle start, msgId=%d, remote:%v\n", request.GetMsgID(), request.GetConnection().RemoteAddr())
		time.Sleep(time.Second * 10)
		//阻塞操作结束
		zlog.Infof("blockRouter handle end, msgId=%d, remote:%v\n", request.GetMsgID(), request.GetConnection().RemoteAddr())
	}

	err := request.GetConnection().SendMsg(2, []byte("pong from server"))
	if err != nil {
		zlog.Error(err)
		return
	}
	zlog.Infof("send pong over, client:%s\n", request.GetConnection().RemoteAddr())
}

func main() {
	s := znet.NewServer()

	s.SetOnConnStart(OnConnectionAdd)
	s.SetOnConnStop(OnConnectionLost)

	s.AddRouter(1, &blockRouter{})

	s.Serve()
}


================================================
FILE: examples/zinx_heartbeat/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"time"
)

// User-defined heartbeat message processing method
// 用户自定义的心跳检测消息处理方法
func myClientHeartBeatMsg(conn ziface.IConnection) []byte {
	return []byte("heartbeat, I am Client, I am alive")
}

// User-defined handling method for remote connection not alive.
// 用户自定义的远程连接不存活时的处理方法
func myClientOnRemoteNotAlive(conn ziface.IConnection) {
	fmt.Println("myClientOnRemoteNotAlive is Called, connID=", conn.GetConnID(), "remoteAddr = ", conn.RemoteAddr())
	//关闭连接
	conn.Stop()
}

// 用户自定义的心跳检测消息处理方法
type myClientHeartBeatRouter struct {
	znet.BaseRouter
}

func (r *myClientHeartBeatRouter) Handle(request ziface.IRequest) {
	fmt.Println("in myClientHeartBeatRouter Handle, recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	myHeartBeatMsgID := 88888

	// Start heartbeating detection. (启动心跳检测)
	client.StartHeartBeatWithOption(3*time.Second, &ziface.HeartBeatOption{
		MakeMsg:          myClientHeartBeatMsg,
		OnRemoteNotAlive: myClientOnRemoteNotAlive,
		Router:           &myClientHeartBeatRouter{},
		HeartBeatMsgID:   uint32(myHeartBeatMsgID),
	})

	client.Start()

	select {}
}


================================================
FILE: examples/zinx_heartbeat/client_default/client_default.go
================================================
package main

import (
	"time"

	"github.com/aceld/zinx/znet"
)

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	// Start heartbeating detection.
	client.StartHeartBeat(3 * time.Second)

	client.Start()

	// wait
	select {}
}


================================================
FILE: examples/zinx_heartbeat/server/conf/zinx.json
================================================
{
  "Name":"Zinx Heartbeat",
  "Host":"127.0.0.1",
  "TcpPort":8999,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogIsolationLevel": 1,
  "HeartbeatMax": 10
}


================================================
FILE: examples/zinx_heartbeat/server/server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"time"
)

// User-defined heartbeat message processing method
// 用户自定义的心跳检测消息处理方法
func myHeartBeatMsg(conn ziface.IConnection) []byte {
	return []byte("heartbeat, I am server, I am alive")
}

// User-defined handling method for remote connection not alive.
// 用户自定义的远程连接不存活时的处理方法
func myOnRemoteNotAlive(conn ziface.IConnection) {
	fmt.Println("myOnRemoteNotAlive is Called, connID=", conn.GetConnID(), "remoteAddr = ", conn.RemoteAddr())
	//关闭连接
	conn.Stop()
}

// User-defined method for handling heartbeat messages (用户自定义的心跳检测消息处理方法)
type myHeartBeatRouter struct {
	znet.BaseRouter
}

func (r *myHeartBeatRouter) Handle(request ziface.IRequest) {
	fmt.Println("in MyHeartBeatRouter Handle, recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}

func main() {
	s := znet.NewServer()

	myHeartBeatMsgID := 88888

	// Start heartbeating detection. (启动心跳检测)
	s.StartHeartBeatWithOption(1*time.Second, &ziface.HeartBeatOption{
		MakeMsg:          myHeartBeatMsg,
		OnRemoteNotAlive: myOnRemoteNotAlive,
		Router:           &myHeartBeatRouter{},
		HeartBeatMsgID:   uint32(myHeartBeatMsgID),
	})

	s.Serve()
}


================================================
FILE: examples/zinx_heartbeat/server_default/conf/zinx.json
================================================
{
  "Name":"Zinx Heartbeat",
  "Host":"127.0.0.1",
  "TcpPort":8999,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogIsolationLevel": 1,
  "HeartbeatMax": 10
}


================================================
FILE: examples/zinx_heartbeat/server_default/server_default.go
================================================
package main

import (
	"github.com/aceld/zinx/znet"
	"time"
)

func main() {
	s := znet.NewServer()

	// Start heartbeating detection.
	s.StartHeartBeat(5 * time.Second)

	s.Serve()
}


================================================
FILE: examples/zinx_interceptor/client/client.go
================================================
package main

import (
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(func(connection ziface.IConnection) {
		_ = connection.SendMsg(1, []byte("hello zinx"))
	})

	client.Start()

	time.Sleep(time.Second)
}


================================================
FILE: examples/zinx_interceptor/interceptors/interceptor_1.go
================================================
package interceptors

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
)

// Custom Interceptor 1

type MyInterceptor struct{}

func (m *MyInterceptor) Intercept(chain ziface.IChain) ziface.IcResp {
	request := chain.Request()
	// This layer is the custom interceptor processing logic, which simply prints the input.
	// (这一层是自定义拦截器处理逻辑,这里只是简单打印输入)
	iRequest := request.(ziface.IRequest)
	zlog.Ins().InfoF("MyInterceptor, Recv:%s", iRequest.GetData())
	return chain.Proceed(chain.Request())
}


================================================
FILE: examples/zinx_interceptor/router/route.go
================================================
package router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type HelloRouter struct {
	znet.BaseRouter
}

func (hr *HelloRouter) Handle(request ziface.IRequest) {
	zlog.Ins().InfoF(string(request.GetData()))
}


================================================
FILE: examples/zinx_interceptor/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/examples/zinx_interceptor/interceptors"
	"github.com/aceld/zinx/examples/zinx_interceptor/router"
	"github.com/aceld/zinx/znet"
)

func main() {
	server := znet.NewServer()

	server.AddRouter(1, &router.HelloRouter{})

	// Add Custom Interceptor
	server.AddInterceptor(&interceptors.MyInterceptor{})

	server.Serve()
}


================================================
FILE: examples/zinx_kcp/client/kcp_client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zpack"
	"github.com/xtaci/kcp-go"
	"io"
	"time"
)

// 模拟客户端
func main() {
	fmt.Println("Client Test ... start")
	// Replace net.Dial with kcp.DialWithOptions
	conn, err := kcp.Dial("127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	dp := zpack.Factory().NewPack(ziface.ZinxDataPack)
	sendMsg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("client test message")))
	_, err = conn.Write(sendMsg)
	if err != nil {
		fmt.Println("client write err: ", err)
		return
	}

	for {
		// Read the "head" section from the stream first. (先读出流中的head部分)
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData)
		if err != nil {
			fmt.Println("client read head err: ", err)
			return
		}

		// Unpack the headData byte stream into msg. (将headData字节流 拆包到msg中)
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("client unpack head err: ", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			// Read the "data" section from the stream. (再读出流中的data部分)
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			// read from io.Reader into msg.Data (根据dataLen从io中读取字节流)
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("client unpack data err")
				return
			}

			fmt.Printf("==> Client receive Msg: ID = %d, len = %d , data = %s\n", msg.ID, msg.DataLen, msg.Data)

			time.Sleep(1 * time.Second)
			_, err = conn.Write(sendMsg)
			if err != nil {
				fmt.Println("client write err: ", err)
				return
			}
		}
	}
}


================================================
FILE: examples/zinx_kcp/server/server.go
================================================
package main

import (
	"errors"
	"fmt"
	"github.com/aceld/zinx/zconf"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

type TestRouter struct {
	znet.BaseRouter
}

var dealTimes = 0

// PreHandle -
func (t *TestRouter) PreHandle(req ziface.IRequest) {
	start := time.Now()

	fmt.Println("--> Call PreHandle")
	if err := req.GetConnection().SendMsg(0, []byte("test1")); err != nil {
		fmt.Println(err)
	}
	elapsed := time.Since(start)
	fmt.Println("cost time:", elapsed)
}

// Handle -
func (t *TestRouter) Handle(req ziface.IRequest) {
	fmt.Println("--> Call Handle")

	if err := Err(); err != nil {
		req.Abort()
		fmt.Println("Insufficient permission")
	}

	dealTimes++
	req.GetConnection().AddCloseCallback(nil, nil, func() {
		fmt.Println("run close callback")
	})

	if err := req.GetConnection().SendMsg(0, []byte("test2")); err != nil {
		fmt.Println(err)
	}

	if dealTimes == 5 {
		req.GetConnection().Stop()
	}

	time.Sleep(1 * time.Millisecond)
}

// PostHandle -
func (t *TestRouter) PostHandle(req ziface.IRequest) {
	fmt.Println("--> Call PostHandle")
	if err := req.GetConnection().SendMsg(0, []byte("test3")); err != nil {
		fmt.Println(err)
	}
}

func Err() error {
	//Specific Business Operation (具体业务操作)
	return errors.New("Test")
}

func main() {
	s := znet.NewUserConfServer(&zconf.Config{
		Mode:               "kcp",
		KcpPort:            7777,
		KcpRecvWindow:      128,
		KcpSendWindow:      128,
		KcpStreamMode:      true,
		KcpACKNoDelay:      false,
		LogDir:             "./",
		LogFile:            "test.log",
		KcpFecDataShards:   10, //代表每10个原始数据块 发3个校验数据块
		KcpFecParityShards: 3,
	})
	s.AddRouter(1, &TestRouter{})
	s.SetOnConnStart(func(conn ziface.IConnection) {
		fmt.Println("--> OnConnStart")
	})
	s.SetOnConnStop(func(conn ziface.IConnection) {
		fmt.Println("--> OnConnStop")
	})
	s.Serve()
}


================================================
FILE: examples/zinx_logger/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(1, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	conn.SetProperty("Name", "刘丹冰")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func DoClientConnectedLost(conn ziface.IConnection) {
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Error("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Error("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	client.AddRouter(0, &c_router.PingRouter{})

	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
}


================================================
FILE: examples/zinx_logger/server/my_logger.go
================================================
package main

import (
	"context"
	"fmt"
)

// User-defined logging method
// The internal engine logging method of zinx can be reset by the logging method of its own business.
// In this example, fmt.Println is used.
// 用户自定义日志方式,
// 可以通过自身业务的日志方式,来重置zinx内部引擎的日志打印方式
// 本例以fmt.Println为例
type MyLogger struct{}

// Without context logging interface
func (l *MyLogger) InfoF(format string, v ...interface{}) {
	fmt.Printf(format, v...)
}

func (l *MyLogger) ErrorF(format string, v ...interface{}) {
	fmt.Printf(format, v...)
}

func (l *MyLogger) DebugF(format string, v ...interface{}) {
	fmt.Printf(format, v...)
}

// Logging interface with context
func (l *MyLogger) InfoFX(ctx context.Context, format string, v ...interface{}) {
	fmt.Println(ctx)
	fmt.Printf(format, v...)
}

func (l *MyLogger) ErrorFX(ctx context.Context, format string, v ...interface{}) {
	fmt.Println(ctx)
	fmt.Printf(format, v...)
}

func (l *MyLogger) DebugFX(ctx context.Context, format string, v ...interface{}) {
	fmt.Println(ctx)
	fmt.Printf(format, v...)
}


================================================
FILE: examples/zinx_logger/server/server.go
================================================
package main

import (
	"fmt"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type TestRouter struct {
	znet.BaseRouter
}

// PreHandle -
func (t *TestRouter) PreHandle(req ziface.IRequest) {
	start := time.Now()

	fmt.Println("--> Call PreHandle")
	if err := req.GetConnection().SendMsg(0, []byte("test1")); err != nil {
		fmt.Println(err)
	}
	elapsed := time.Since(start)
	fmt.Println("elapsed:", elapsed)
}

// Handle -
func (t *TestRouter) Handle(req ziface.IRequest) {
	fmt.Println("--> Call Handle")

	if err := req.GetConnection().SendMsg(0, []byte("test2")); err != nil {
		fmt.Println(err)
	}
}

// PostHandle -
func (t *TestRouter) PostHandle(req ziface.IRequest) {
	fmt.Println("--> Call PostHandle")
	if err := req.GetConnection().SendMsg(0, []byte("test3")); err != nil {
		fmt.Println(err)
	}
}

func main() {
	s := znet.NewServer()
	s.AddRouter(1, &TestRouter{})
	zlog.SetLogger(new(MyLogger))
	s.Serve()
}


================================================
FILE: examples/zinx_metrics/client/c1/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(100, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	//设置两个连接属性,在连接创建之后
	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func DoClientConnectedLost(conn ziface.IConnection) {
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Debug("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Debug("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)

	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_metrics/client/c2/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(100, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func DoClientConnectedLost(conn ziface.IConnection) {
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Debug("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Debug("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)

	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_metrics/server/conf/zinx.json
================================================
{
  "Name":"MyZinxServer001",
  "Host":"0.0.0.0",
  "TCPPort":8999,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogIsolationLevel": 0,
  "PrometheusMetricsEnable": true,
  "PrometheusServer": true,
  "PrometheusListen": "0.0.0.0:20004"
}


================================================
FILE: examples/zinx_metrics/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/examples/zinx_server/s_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

func DoConnectionBegin(conn ziface.IConnection) {
	zlog.Ins().InfoF("DoConnectionBegin is Called ...")

	conn.SetProperty("Name", "Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		zlog.Error(err)
	}
}

func DoConnectionLost(conn ziface.IConnection) {
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Ins().InfoF("Conn Property Name = %v", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Ins().InfoF("Conn Property Home = %v", home)
	}

	zlog.Ins().InfoF("Conn is Lost")
}

// usage:$  curl 0.0.0.0:20004/metrics
// to get Metrics
func main() {
	s := znet.NewServer()

	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	s.AddRouter(100, &s_router.PingRouter{})
	s.AddRouter(1, &s_router.HelloZinxRouter{})

	s.Serve()
}


================================================
FILE: examples/zinx_mutiport/client8999/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(100, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	//设置两个连接属性,在连接创建之后
	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func DoClientConnectedLost(conn ziface.IConnection) {
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Debug("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Debug("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)

	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_mutiport/client9000/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(100, []byte("Ping...[FromClient]"))
		if err != nil {
			fmt.Println(err)
			zlog.Error(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func DoClientConnectedLost(conn ziface.IConnection) {
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Debug("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Debug("Conn Property Home = ", home)
	}

	zlog.Debug("DoClientConnectedLost is Called ... ")
}

func main() {
	client := znet.NewClient("127.0.0.1", 9000)

	client.SetOnConnStart(DoClientConnectedBegin)
	client.SetOnConnStop(DoClientConnectedLost)

	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)

	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_mutiport/server/server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_server/s_router"
	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
)

// Execute when creating a connection (创建连接的时候执行)
func DoConnectionBegin(conn ziface.IConnection) {
	zlog.Ins().InfoF("DoConnectionBegin is Called ...")

	//设置两个连接属性,在连接创建之后
	conn.SetProperty("Name", "Aceld")
	conn.SetProperty("Home", "https://yuque.com/@aceld")

	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		zlog.Error(err)
	}
}

// Execute when connection lost (连接断开的时候执行)
func DoConnectionLost(conn ziface.IConnection) {
	// Query the Name and Home properties of the conn before destroying the connectio
	// 在连接销毁之前,查询conn的Name,Home属性
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Ins().InfoF("Conn Property Name = %v", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Ins().InfoF("Conn Property Home = %v", home)
	}

	zlog.Ins().InfoF("Conn is Lost")
}

func main() {

	var i = 0

	for i < 2 {

		port := 8999 + i
		s := znet.NewUserConfServer(&zconf.Config{
			TCPPort: port,
			Name:    fmt.Sprintf("MyZinxServer-port:%d", port),
		})

		s.SetOnConnStart(DoConnectionBegin)
		s.SetOnConnStop(DoConnectionLost)

		s.AddRouter(100, &s_router.PingRouter{})
		s.AddRouter(1, &s_router.HelloZinxRouter{})

		go s.Serve()

		i++
	}

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
}


================================================
FILE: examples/zinx_new_router/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

// 模拟客户端
func main() {

	fmt.Println("Client Test ... start")
	// Send a test request after 3 seconds to give the server a chance to start the service. (3秒之后发起测试请求,给服务端开启服务的机会)
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	dp := zpack.Factory().NewPack(ziface.ZinxDataPack)
	msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("client test message")))
	_, err = conn.Write(msg)
	if err != nil {
		fmt.Println("client write err: ", err)
		return
	}

	for {
		// Read the "head" section from the stream first. (先读出流中的head部分)
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData)
		if err != nil {
			fmt.Println("client read head err: ", err)
			return
		}

		// Unpack the headData byte stream into msg. (将headData字节流 拆包到msg中)
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("client unpack head err: ", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			// Read the "data" section from the stream. (再读出流中的data部分)
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			// read from io.Reader into msg.Data (根据dataLen从io中读取字节流)
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("client unpack data err")
				return
			}

			fmt.Printf("==> Client receive Msg: ID = %d, len = %d , data = %s\n", msg.ID, msg.DataLen, msg.Data)
		}
	}
}


================================================
FILE: examples/zinx_new_router/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.10 demoApp",
  "Host":"127.0.0.1",
  "TCPPort":7777,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogDir": "./mylog",
  "LogFile":"zinx.log"
}


================================================
FILE: examples/zinx_new_router/server/server.go
================================================
package main

import (
	"errors"
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"time"
)

type TestRouter struct {
	znet.BaseRouter
}

// PreHandle -
func (t *TestRouter) PreHandle(req ziface.IRequest) {
	start := time.Now()

	fmt.Println("--> Call PreHandle")
	if err := req.GetConnection().SendMsg(0, []byte("test1")); err != nil {
		fmt.Println(err)
	}
	elapsed := time.Since(start)
	fmt.Println("cost time:", elapsed)
}

// Handle -
func (t *TestRouter) Handle(req ziface.IRequest) {
	fmt.Println("--> Call Handle")

	// Simulated scenario - In the event of an expected error such as incorrect permissions or incorrect information,
	// subsequent function execution will be stopped, but this function will be fully executed.
	// 模拟场景- 出现意料之中的错误 如权限不对或者信息错误 则停止后续函数执行,但是次函数会执行完毕
	if err := Err(); err != nil {
		req.Abort()
		fmt.Println("Insufficient permission")
	}

	// Simulation scenario - In case of a certain situation, repeat the above operation.
	// 模拟场景- 出现某种情况,重复上面的操作
	/*
		if err := Err(); err != nil {
			req.Goto(znet.PRE_HANDLE)
			fmt.Println("repeat")
		}
	*/

	if err := req.GetConnection().SendMsg(0, []byte("test2")); err != nil {
		fmt.Println(err)
	}

	time.Sleep(1 * time.Millisecond)
}

// PostHandle -
func (t *TestRouter) PostHandle(req ziface.IRequest) {
	fmt.Println("--> Call PostHandle")
	if err := req.GetConnection().SendMsg(0, []byte("test3")); err != nil {
		fmt.Println(err)
	}
}

func Err() error {
	//Specific Business Operation (具体业务操作)
	return errors.New("Test")
}

func main() {
	s := znet.NewServer()
	s.AddRouter(1, &TestRouter{})
	s.Serve()
}


================================================
FILE: examples/zinx_protobuf/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
	"github.com/aceld/zinx/znet"
	"github.com/golang/protobuf/proto"
	"os"
	"os/signal"
	"time"
)

type PositionClientRouter struct {
	znet.BaseRouter
}

func (this *PositionClientRouter) Handle(request ziface.IRequest) {
	fmt.Println("Handle....")

	msg := &pb.Position{}
	err := proto.Unmarshal(request.GetData(), msg)
	if err != nil {
		fmt.Println("Position Unmarshal error ", err, " data = ", request.GetData())
		return
	}

	fmt.Printf("recv from server : msgId=%+v, data=%+v\n", request.GetMsgID(), msg)
}

// 客户端自定义业务
func business(conn ziface.IConnection) {

	for {

		msg := &pb.Position{}
		msg.X = 1
		msg.Y = 2
		msg.Z = 3
		msg.V = 4

		data, err := proto.Marshal(msg)
		if err != nil {
			fmt.Println("proto Marshal error = ", err, " msg = ", msg)
			break
		}

		err = conn.SendMsg(0, data)
		if err != nil {
			fmt.Println(err)
			break
		}

		time.Sleep(1 * time.Second)
	}
}

func DoClientConnectedBegin(conn ziface.IConnection) {
	conn.SetProperty("Name", "刘丹冰Aceld")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func wait() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
}

func main() {
	client := znet.NewClient("127.0.0.1", 8999)

	client.SetOnConnStart(DoClientConnectedBegin)

	client.AddRouter(0, &PositionClientRouter{})

	client.Start()

	wait()
}


================================================
FILE: examples/zinx_protobuf/server/server.go
================================================
package main

import (
	"fmt"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"github.com/golang/protobuf/proto"
)

type PositionServerRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PositionServerRouter) Handle(request ziface.IRequest) {

	msg := &pb.Position{}
	err := proto.Unmarshal(request.GetData(), msg)
	if err != nil {
		fmt.Println("Position Unmarshal error ", err, " data = ", request.GetData())
		return
	}

	fmt.Printf("recv from client : msgId=%+v, data=%+v\n", request.GetMsgID(), msg)

	msg.X += 1
	msg.Y += 1
	msg.Z += 1
	msg.V += 1

	data, err := proto.Marshal(msg)
	if err != nil {
		fmt.Println("proto Marshal error = ", err, " msg = ", msg)
		return
	}

	err = request.GetConnection().SendMsg(0, data)

	if err != nil {
		zlog.Error(err)
	}
}

func main() {
	s := znet.NewServer()

	s.AddRouter(0, &PositionServerRouter{})

	s.Serve()
}


================================================
FILE: examples/zinx_routerSlices/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"net"
)

func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:8999")
	if err != nil {
		fmt.Println("client start err, exit!", err)
		return
	}

	dp := zpack.NewDataPack()
	msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("ZinxPing")))
	_, err = conn.Write(msg)
	if err != nil {
		fmt.Println("write error err ", err)
		return
	}

}


================================================
FILE: examples/zinx_routerSlices/default_func_server/server.go
================================================
package main

import (
	"fmt"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

func DefaultTest1(request ziface.IRequest) {
	fmt.Println("test1")
}
func DefaultTest2(request ziface.IRequest) {
	time.Sleep(1)
	arr := make([]int, 1)
	fmt.Println(arr[1])
}

func main() {
	s := znet.NewDefaultRouterSlicesServer()
	s.AddRouterSlices(1, DefaultTest1, DefaultTest2)
	s.Serve()
}


================================================
FILE: examples/zinx_routerSlices/router_func_server/server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

func Auth1(request ziface.IRequest) {

	// Verify business, default to pass. (验证业务 默认固定放行)
	fmt.Println("I am the Auth1, I will always pass.")
	// I am validation handler 1, and I must pass.
	// Note that the next function will start executing and return here after all functions are executed.
	// (注意是进入下一个函数开始执行,全部执行完后 回到此处)
	request.RouterSlicesNext()
}

func Auth2(request ziface.IRequest) {
	// I am the validation handler 2, and by default, I do not allow the request to pass.(验证业务 默认固定不放行)

	// Terminate execution function, no more handlers will be executed after this one.(终结执行函数,再这个处理器结束后不会在执行后面的处理器)
	request.Abort()
	fmt.Println("I am the Auth2, I will definitely not pass.")
	fmt.Println("The business terminates here and the subsequent handlers will not be executed.")
}

func Auth3(request ziface.IRequest) {

	fmt.Println("I am the group validation function.")
}

// I am a business function.
func TestFunc(request ziface.IRequest) {
	fmt.Println("I am a business function.")
}

func main() {

	// New version usage and explanation.(新版本使用方法以及说明)
	server := znet.NewUserConfServer(&zconf.Config{RouterSlicesMode: true, TCPPort: 8999, Host: "127.0.0.1"})

	// Simulation scenario 1: A normal business that only executes a single operation function separately.
	// 模拟场景 1,普通业务单独只执行一个操作函数
	//server.AddRouterSlices(1, TestFunc)

	// Simulated scenario 2: All operations below require verification of request permissions, so a verification function is needed.
	// the verification component has been added to all the routes under the use method, such as 1 and 2.
	// 模拟场景 2, 以下所有操作都需要验证请求权限,所以需要一个验证函数
	// 将验证组件添加到了所有再use方法下的所有路由中了 如1,2 中都会带有
	//routerSlices := server.Use(Auth1)
	//routerSlices.AddHandler(1, TestFunc)
	//routerSlices.AddHandler(2, TestFunc)

	// Equivalent to the following:(等价于下面:)
	//routerSlices.AddHandler(1, Auth1, TestFunc)

	// Simulated scenario 3: Authorization is required, but some route operations require additional verification.
	// 模拟场景3 需要权限,但是某些路由操作需要更多额外验证
	server.Use(Auth1)
	group1 := server.Group(1, 2, Auth3)
	{
		// MsgId=1, there will be Auth3 and Auth1. (1中就会有Auth3和Auth1)
		group1.AddHandler(1, TestFunc)

		// More specific scenario: Some operations within the group require an additional validation process.
		// 更特殊的情况,组内另一些操作还需要另一道校验处理
		group1.Use(Auth2)
		// MsgId=2, Auth3 and Auth1 will be added to all routes under the use method.
		// 2中就会有Auth1和Auth3以及Auth2
		group1.AddHandler(2, TestFunc)

	}
	// MsgId=3, Auth3 will not be included. (3中就不会有Auth3)
	server.AddRouterSlices(3, TestFunc)

	server.Serve()

}


================================================
FILE: examples/zinx_routerSlices/router_group_server/server.go
================================================
package main

import (
	"fmt"

	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

func Test1(request ziface.IRequest) {
	fmt.Println("test1")
}
func Test2(request ziface.IRequest) {
	fmt.Println("Test2")
}
func Test3(request ziface.IRequest) {
	fmt.Println("Test3")
}
func Test4(request ziface.IRequest) {
	fmt.Println("Test4")
}
func Test5(request ziface.IRequest) {
	fmt.Println("Test5")
}
func Test6(request ziface.IRequest) {
	fmt.Println("Test6")
}

type router struct {
	znet.BaseRouter
}

func (r *router) PreHandle(req ziface.IRequest) {
	fmt.Println(" hello router1")
}
func (r *router) Handle(req ziface.IRequest) {
	req.Abort()
	fmt.Println(" hello router2")
}
func (r *router) PostHandle(req ziface.IRequest) {
	fmt.Println(" hello router3")
}

func main() {

	// Old version router method (旧版本路由方法)
	//{
	//	server := znet.NewUserConfServer(&zconf.Config{TCPPort: 8999, Host: "127.0.0.1"})
	//
	//	// Even without manually calling the router mode, the default is 1 (old version) 即使不手动调路由模式也可以,默认是1(旧版本)
	//	//server := znet.NewServer()
	//
	//	// Old version runs normally(旧版正常执行)
	//	r := &router{}
	//	server.AddRouter(1, r)
	//	server.Serve()
	//}
	//{

	// New version usage and explanation(新版本使用方法以及说明)
	{
		server := znet.NewUserConfServer(&zconf.Config{RouterSlicesMode: true, TCPPort: 8999, Host: "127.0.0.1"})
		// Grouping(分组)
		group := server.Group(3, 10, Test1)

		// Add router. Will panic if not within the group range.(添加路由 如果不在组范围会直接panic)
		//group.AddHandler(11, Test2)

		// Within the group, not affected by Use, has processors 1 and 2.(在组中 不受Use影响 有 1 2 处理器)
		group.AddHandler(3, Test2)

		// Not within the group and before Use, only has its own processor 3.(既不在组里也在Use之前只会有自己的处理器 3)
		server.AddRouterSlices(1, Test3)

		// If you want the group processor to have priority, you should do the following before Use.
		// You can manually add it via group.AddHandler(5, Test4, Test5,Test2, Test3, Test6)
		// or use the Group's Use method as shown below, which would have the order of 1 4 5 6 and not be affected by Use.
		// 如果希望group处理器优先,应当在Use之前如下操作
		// 可以手动添加 入 group.AddHandler(5, Test4, Test5,Test2, Test3, Test6)
		// 或者如下使用Group的Use方法 那么就是 1 4 5 6的顺序 不被use影响
		group.Use(Test2, Test3)
		group.AddHandler(5, Test4, Test5, Test6)

		// Common components, but not affected by the groups or routers before Use. (公共组件,但是,在使用Use之前的组或者路由不会影响到)
		router := server.Use(Test4, Test5)
		// Add router. Not within the group but is affected by Use, has processors 4, 5, and 6.
		// (添加路由 不在组中但是收Use影响 有4 5 6处理器)
		router.AddHandler(2, Test6)

		// Within the group and affected by Use, has all processors in the order of 4, 5, 1, 2, 3, 6 because the processors in Use are always at the forefront.
		// (在组里也受到Use影响 有所有处理器 且顺序应该是 4 5 1 2 3 6 因为use中的处理器始终在最前端)
		group.AddHandler(4, Test6)

		server.Serve()
	}

}


================================================
FILE: examples/zinx_server/Makefile
================================================
PROJECT_NAME:=zinx_server
VERSION:=v1



.PHONY: image run build clean

build:
	bash build.sh ${PROJECT_NAME}

image:
	docker build -t ${PROJECT_NAME}:${VERSION} .

run:
	docker run  -itd \
	-p 8999:8999 \
	${PROJECT_NAME}:${VERSION}


clean:
	rm -rf ${PROJECT_NAME} 



================================================
FILE: examples/zinx_server/build.sh
================================================
#!/bin/bash

set -e

APP_NAME=$1
APP_VERSION=v$(cat version)
BUILD_VERSION=$(git log -1 --oneline)
BUILD_TIME=$(date "+%FT%T%z")
GIT_REVISION=$(git rev-parse --short HEAD)
GIT_BRANCH=$(git name-rev --name-only HEAD)
GO_VERSION=$(go version)


go build -ldflags " \
	-X 'main.AppName=${APP_NAME}' 			\
	-X 'main.AppVersion=${APP_VERSION}'     \
	-X 'main.BuildVersion=${BUILD_VERSION//\'/_}' \
	-X 'main.BuildTime=${BUILD_TIME}'       \
	-X 'main.GitRevision=${GIT_REVISION}'   \
	-X 'main.GitBranch=${GIT_BRANCH}'       \
	-X 'main.GoVersion=${GO_VERSION}'       \
	" -o $APP_NAME


================================================
FILE: examples/zinx_server/conf/zinx.json
================================================
{
  "Name":"zinx server Demo",
  "Host":"127.0.0.1",
  "TCPPort":8999,
  "MaxConn":3,
  "WorkerMode": "",
  "WorkerPoolSize":10,
  "LogDir": "./mylog",
  "LogFile":"zinx.log",
  "LogIsolationLevel": 0,
  "Mode":"kcp"
}


================================================
FILE: examples/zinx_server/dockerfile
================================================
FROM centos:8
COPY zinx_server /zinx-server
COPY /conf/zinx.json /conf/zinx.json
WORKDIR /
EXPOSE  8999

ENTRYPOINT [ "/zinx-server" ]



================================================
FILE: examples/zinx_server/main.go
================================================
/**
* @Author: Aceld
* @Date: 2020/12/24 00:24
* @Mail: danbing.at@gmail.com
*    zinx server demo
 */
package main

import (
	"github.com/aceld/zinx/examples/zinx_server/s_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// DoConnectionBegin Executed when creating a connection.
// 创建连接的时候执行
func DoConnectionBegin(conn ziface.IConnection) {
	zlog.Ins().InfoF("DoConnectionBegin is Called ...")

	//设置两个连接属性,在连接创建之后
	conn.SetProperty("Name", "Aceld")
	conn.SetProperty("Home", "https://www.kancloud.cn/@aceld")

	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		zlog.Error(err)
	}
}

// 连接断开的时候执行
// DoConnectionLost Executed when the connection is closed.
func DoConnectionLost(conn ziface.IConnection) {
	//在连接销毁之前,查询conn的Name,Home属性
	// Query the Name and Home properties of conn before destroying the connection.
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Ins().InfoF("Conn Property Name = %v", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Ins().InfoF("Conn Property Home = %v", home)
	}

	zlog.Ins().InfoF("Conn is Lost")
}

func main() {
	// Create a server
	s := znet.NewServer()

	// Register a hook callback function for the connection
	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	// Configure routing.
	s.AddRouter(100, &s_router.PingRouter{})
	s.AddRouter(1, &s_router.HelloZinxRouter{})

	// Start Service
	s.Serve()
}


================================================
FILE: examples/zinx_server/s_router/hello.go
================================================
package s_router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type HelloZinxRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
	zlog.Ins().DebugF("Call HelloZinxRouter Handle")
	// Read the data from the client first, then send back "ping...ping...ping"
	zlog.Ins().DebugF("recv from client : msgId=%d, data=%+v, len=%d", request.GetMsgID(), string(request.GetData()), len(request.GetData()))

	err := request.GetConnection().SendBuffMsg(3, []byte("Hello Zinx Router[FromServer]"))
	if err != nil {
		zlog.Error(err)
	}
}


================================================
FILE: examples/zinx_server/s_router/ping.go
================================================
package s_router

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {

	zlog.Ins().DebugF("Call PingRouter Handle")
	// Read the data from the client first, then send back "ping...ping...ping".
	zlog.Ins().DebugF("recv from client : msgId=%d, data=%+v, len=%d", request.GetMsgID(), string(request.GetData()), len(request.GetData()))

	err := request.GetConnection().SendMsg(2, []byte("pong-server"))
	if err != nil {
		zlog.Error(err)
	}
}


================================================
FILE: examples/zinx_server/version
================================================
v 1.0.0


================================================
FILE: examples/zinx_tls/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

// PongRouter pong test 自定义路由
type PongRouter struct {
	znet.BaseRouter
}

// Handle Pong Handle
func (this *PongRouter) Handle(request ziface.IRequest) {

	zlog.Debug("Call PongRouter Handle")
	//先读取服务器返回的数据
	zlog.Debug("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

}

func wait() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
}

func main() {
	// Create a TLS client.
	c := znet.NewTLSClient("127.0.0.1", 8899)

	c.SetOnConnStart(func(connection ziface.IConnection) {
		go func() {
			for {
				err := connection.SendMsg(1, []byte("Ping with TLS"))

				if err != nil {
					fmt.Println(err)
					break
				}

				time.Sleep(1 * time.Second)
			}
		}()

	})

	c.AddRouter(2, &PongRouter{})

	c.Start()

	wait()
}


================================================
FILE: examples/zinx_tls/server/server.go
================================================
package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"math/big"
	"os"
	"time"

	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// PingRouter ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Handle Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {

	zlog.Debug("Call PingRouter Handle")
	zlog.Debug("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(2, []byte("Pong with TLS"), ziface.WithSendMsgTimeout(time.Millisecond*10))
	if err != nil {
		zlog.Error(err)
	}
}

// genExampleCrtAndKeyFile
// Generate certificate and key files for testing purposes only! Please customize this function or use openssl to generate them for actual use.
// (仅测试时生成证书和密钥文件!!实际使用请自定义该函数或者用openssl自行生成)
// Reference for generating certificate and private key using openssl : https://blog.csdn.net/qq_44637753/article/details/124152315
// (openssl生成证书和私钥方法参考 https://blog.csdn.net/qq_44637753/article/details/124152315)
func genExampleCrtAndKeyFile(crtFileName, KeyFileName string) (err error) {
	// If already exists, regenerate.(如果已存在则重新生成)
	_ = os.Remove(crtFileName)
	_ = os.Remove(KeyFileName)

	defer func() {
		if err != nil {
			// If there is an error during the process, delete the generated certificate and private key files.
			// (如果期间发生错误,删除以及生成的证书和私钥文件)
			_ = os.Remove(crtFileName)
			_ = os.Remove(KeyFileName)
		}
	}()
	// Generating a private key.(生成私钥)
	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

	// Creating a certificate template.(创建证书模板)
	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		return err
	}

	template := x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			Organization: []string{"Beijing University of Post and Telecommunication"},
		},

		NotBefore: time.Now(),
		NotAfter:  time.Now().Add(24 * time.Hour * 365 * 10), // The certificate is valid for ten years. (证书十年之内有效)

		KeyUsage:              x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
	}

	// Generating a certificate.(生成证书)
	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
	if err != nil {
		return err
	}

	// serialize the certificate file.(序列化证书文件)
	pemCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	if pemCert == nil {
		return err
	}
	if err := os.WriteFile(crtFileName, pemCert, 0644); err != nil {
		return err
	}

	// Generating private key file(生成私钥文件)
	privateBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
	if err != nil {
		return err
	}
	pemKey := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateBytes})
	if pemKey == nil {
		return err
	}
	if err := os.WriteFile(KeyFileName, pemKey, 0600); err != nil {
		return err
	}

	return nil
}

func main() {
	// Generate certificate and key files for testing purposes only!! Please customize this function or use openssl to generate them yourself in actual use.
	// Refer to this link for how to generate certificates and private keys using openssl: https://blog.csdn.net/qq_44637753/article/details/124152315
	// 生成测试用的证书和密钥文件!!仅测试时生成证书和密钥文件!!实际使用请自定义该函数或者用openssl自行生成
	// openssl生成证书和私钥方法参考 https://blog.csdn.net/qq_44637753/article/details/124152315
	certFile := "cert.pem"
	keyFile := "key.pem"
	err := genExampleCrtAndKeyFile(certFile, keyFile)
	if err != nil {
		panic(err)
	}
	defer func() {
		// example中的证书和私钥文件仅作测试时使用 测试结束后删除
		// The certificate and private key files in the example are only used for testing purposes. Please delete them after the test is completed.
		_ = os.Remove(certFile)
		_ = os.Remove(keyFile)
	}()

	// Create a server, and if CertFile and PrivateKeyFile are specified, the server will start in TLS mode.
	// 创建一个server,当指定了CertFile和PrivateKeyFile时服务器开启TLS模式
	s := znet.NewUserConfServer(&zconf.Config{
		TCPPort:        8899,
		CertFile:       certFile, // 证书文件
		PrivateKeyFile: keyFile,  // 密钥文件
	})

	s.AddRouter(1, &PingRouter{})

	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.10Test/client0/Client0.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.10Test/client1/Client1.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for n := 3; n >= 0; n-- {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.10Test/server/Server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))
	if err != nil {
		fmt.Println(err)
	}
}

type HelloZinxRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call HelloZinxRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(1, []byte("Hello Zinx Router V0.10"))
	if err != nil {
		fmt.Println(err)
	}
}

// 创建连接的时候执行
func DoConnectionBegin(conn ziface.IConnection) {
	fmt.Println("DoConnectionBegin is Called ... ")

	//设置两个连接属性,在连接创建之后
	fmt.Println("Set conn Name, Home done!")
	conn.SetProperty("Name", "Aceld")
	conn.SetProperty("Home", "https://www.jianshu.com/u/35261429b7f1")

	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		fmt.Println(err)
	}
}

// 连接断开的时候执行
func DoConnectionLost(conn ziface.IConnection) {
	//在连接销毁之前,查询conn的Name,Home属性
	if name, err := conn.GetProperty("Name"); err == nil {
		fmt.Println("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		fmt.Println("Conn Property Home = ", home)
	}

	fmt.Println("DoConneciotnLost is Called ... ")
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//注册连接hook回调函数
	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	//配置路由
	s.AddRouter(0, &PingRouter{})
	s.AddRouter(1, &HelloZinxRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.10Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.10 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3,
  "WorkerPoolSize":10
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.11Test/client0/Client0.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.11Test/client1/Client1.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for n := 3; n >= 0; n-- {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.11Test/server/Server.go
================================================
/**
* @Author: Aceld
* @Date: 2019/4/30 17:42
* @Mail: danbing.at@gmail.com
*  ZinxV0.11测试,测试Zinx 日志模块功能 zlog模块
 */
package main

import (
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {

	zlog.Debug("Call PingRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	zlog.Debug("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))
	if err != nil {
		zlog.Error(err)
	}
}

type HelloZinxRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
	zlog.Debug("Call HelloZinxRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	zlog.Debug("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(1, []byte("Hello Zinx Router V0.10"))
	if err != nil {
		zlog.Error(err)
	}
}

// 创建连接的时候执行
func DoConnectionBegin(conn ziface.IConnection) {
	zlog.Debug("DoConnectionBegin is Called ... ")

	//设置两个连接属性,在连接创建之后
	zlog.Debug("Set conn Name, Home done!")
	conn.SetProperty("Name", "Aceld")
	conn.SetProperty("Home", "https://www.jianshu.com/u/35261429b7f1")

	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		zlog.Error(err)
	}
}

// 连接断开的时候执行
func DoConnectionLost(conn ziface.IConnection) {
	//在连接销毁之前,查询conn的Name,Home属性
	if name, err := conn.GetProperty("Name"); err == nil {
		zlog.Error("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		zlog.Error("Conn Property Home = ", home)
	}

	zlog.Debug("DoConneciotnLost is Called ... ")
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//注册连接hook回调函数
	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	//配置路由
	s.AddRouter(0, &PingRouter{})
	s.AddRouter(1, &HelloZinxRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.11Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.10 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3,
  "WorkerPoolSize":10,
  "LogDir": "./mylog",
  "LogFile":"zinx.log"
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.1Test/client/client.go
================================================
package main

import (
	"fmt"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		_, err := conn.Write([]byte("hahaha"))
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		buf := make([]byte, 512)
		cnt, err := conn.Read(buf)
		if err != nil {
			fmt.Println("read buf error ")
			return
		}

		fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.1Test/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/znet"
)

// Server 模块的测试函数
func main() {

	/*
		服务端测试
	*/
	//1 创建一个server 句柄 s
	// s := znet.NewServer("[zinx V0.1]")
	s := znet.NewServer()

	//2 开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.2Test/client/client.go
================================================
package main

import (
	"fmt"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		_, err := conn.Write([]byte("hahaha"))
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		buf := make([]byte, 512)
		cnt, err := conn.Read(buf)
		if err != nil {
			fmt.Println("read buf error ")
			return
		}

		fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.2Test/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/znet"
)

// Server 模块的测试函数
func main() {

	/*
		服务端测试
	*/
	//1 创建一个server 句柄 s
	// s := znet.NewServer("[zinx V0.2]")

	s := znet.NewServer()

	//2 开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.3Test/client/client.go
================================================
package main

import (
	"fmt"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		_, err := conn.Write([]byte("Zinx V0.3"))
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		buf := make([]byte, 512)
		cnt, err := conn.Read(buf)
		if err != nil {
			fmt.Println("read buf error ")
			return
		}

		fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.3Test/server/server.go
================================================
package main

import (
	"fmt"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Test PreHandle
func (this *PingRouter) PreHandle(request ziface.IRequest) {
	fmt.Println("Call Router PreHandle")
	_, err := request.GetConnection().GetTCPConnection().Write([]byte("before ping ....\n"))
	if err != nil {
		fmt.Println("call back ping ping ping error")
	}
}

// Test Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	_, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n"))
	if err != nil {
		fmt.Println("call back ping ping ping error")
	}
}

// Test PostHandle
func (this *PingRouter) PostHandle(request ziface.IRequest) {
	fmt.Println("Call Router PostHandle")
	_, err := request.GetConnection().GetTCPConnection().Write([]byte("After ping .....\n"))
	if err != nil {
		fmt.Println("call back ping ping ping error")
	}
}

func main() {
	//创建一个server句柄
	// s := znet.NewServer("[zinx V0.3]")
	s := znet.NewServer()

	// s.AddRouter(&PingRouter{})
	s.AddRouter(3, &PingRouter{})
	//2 开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.4Test/client/client.go
================================================
package main

import (
	"fmt"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		_, err := conn.Write([]byte("Zinx V0.3"))
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		buf := make([]byte, 512)
		cnt, err := conn.Read(buf)
		if err != nil {
			fmt.Println("read buf error ")
			return
		}

		fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.4Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.4 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.4Test/server/server.go
================================================
package main

import (
	"fmt"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Test PreHandle
func (this *PingRouter) PreHandle(request ziface.IRequest) {
	fmt.Println("Call Router PreHandle")
	_, err := request.GetConnection().GetTCPConnection().Write([]byte("before ping ....\n"))
	if err != nil {
		fmt.Println("call back ping ping ping error")
	}
}

// Test Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	_, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n"))
	if err != nil {
		fmt.Println("call back ping ping ping error")
	}
}

// Test PostHandle
func (this *PingRouter) PostHandle(request ziface.IRequest) {
	fmt.Println("Call Router PostHandle")
	_, err := request.GetConnection().GetTCPConnection().Write([]byte("After ping .....\n"))
	if err != nil {
		fmt.Println("call back ping ping ping error")
	}
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//配置路由
	// s.AddRouter(&PingRouter{})
	s.AddRouter(4, &PingRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.5Test/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(0, []byte("Zinx V0.5 Client Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.5Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.5 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.5Test/server/server.go
================================================
package main

import (
	"fmt"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Test Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	//回写数据
	/*
		_, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n"))
		if err != nil {
			fmt.Println("call back ping ping ping error")
		}
	*/
	err := request.GetConnection().SendMsg(1, []byte("ping...ping...ping"))
	if err != nil {
		fmt.Println(err)
	}
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//配置路由
	s.AddRouter(5, &PingRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/client0/Client0.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(0, []byte("Zinx V0.6 Client0 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/client1/Client1.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("Zinx V0.6 Client1 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/server/Server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendMsg(0, []byte("ping...ping...ping"))
	if err != nil {
		fmt.Println(err)
	}
}

type HelloZinxRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call HelloZinxRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendMsg(1, []byte("Hello Zinx Router V0.6"))
	if err != nil {
		fmt.Println(err)
	}
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//配置路由
	s.AddRouter(0, &PingRouter{})
	s.AddRouter(1, &HelloZinxRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.6 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.8Test/client0/Client0.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.8Test/client1/Client1.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.8Test/server/Server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendMsg(0, []byte("ping...ping...ping"))
	if err != nil {
		fmt.Println(err)
	}
}

type HelloZinxRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call HelloZinxRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendMsg(1, []byte("Hello Zinx Router V0.8"))
	if err != nil {
		fmt.Println(err)
	}
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//配置路由
	s.AddRouter(0, &PingRouter{})
	s.AddRouter(1, &HelloZinxRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.8Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.8 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3,
  "WorkerPoolSize":10
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.9Test/client0/Client0.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.9Test/client1/Client1.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
	"time"
)

/*
模拟客户端
*/
func main() {

	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for n := 3; n >= 0; n-- {
		//发封包message消息
		dp := zpack.NewDataPack()
		msg, _ := dp.Pack(zpack.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, dp.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			msg := msgHead.(*zpack.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}

		time.Sleep(1 * time.Second)
	}
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.9Test/server/Server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// ping test 自定义路由
type PingRouter struct {
	znet.BaseRouter
}

// Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call PingRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))
	if err != nil {
		fmt.Println(err)
	}
}

type HelloZinxRouter struct {
	znet.BaseRouter
}

// HelloZinxRouter Handle
func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
	fmt.Println("Call HelloZinxRouter Handle")
	//先读取客户端的数据,再回写ping...ping...ping
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))

	err := request.GetConnection().SendBuffMsg(1, []byte("Hello Zinx Router V0.8"))
	if err != nil {
		fmt.Println(err)
	}
}

// 创建连接的时候执行
func DoConnectionBegin(conn ziface.IConnection) {
	fmt.Println("DoConnectionBegin is Called ... ")
	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		fmt.Println(err)
	}
}

// 连接断开的时候执行
func DoConnectionLost(conn ziface.IConnection) {
	fmt.Println("DoConneciotnLost is Called ... ")
}

func main() {
	//创建一个server句柄
	s := znet.NewServer()

	//注册连接hook回调函数
	s.SetOnConnStart(DoConnectionBegin)
	s.SetOnConnStop(DoConnectionLost)

	//配置路由
	s.AddRouter(0, &PingRouter{})
	s.AddRouter(1, &HelloZinxRouter{})

	//开启服务
	s.Serve()
}


================================================
FILE: examples/zinx_version_ex/ZinxV0.9Test/server/conf/zinx.json
================================================
{
  "Name":"zinx v-0.8 demoApp",
  "Host":"127.0.0.1",
  "TcpPort":7777,
  "MaxConn":3,
  "WorkerPoolSize":10
}


================================================
FILE: examples/zinx_version_ex/datapackDemo/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"net"
)

func main() {
	//客户端goroutine,负责模拟粘包的数据,然后进行发送
	conn, err := net.Dial("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("client dial err:", err)
		return
	}

	//创建一个封包对象 dp
	dp := zpack.NewDataPack()

	//封装一个msg1包
	msg1 := &zpack.Message{
		ID:      0,
		DataLen: 5,
		Data:    []byte{'h', 'e', 'l', 'l', 'o'},
	}

	sendData1, err := dp.Pack(msg1)
	if err != nil {
		fmt.Println("client pack msg1 err:", err)
		return
	}

	msg2 := &zpack.Message{
		ID:      1,
		DataLen: 7,
		Data:    []byte{'w', 'o', 'r', 'l', 'd', '!', '!'},
	}
	sendData2, err := dp.Pack(msg2)
	if err != nil {
		fmt.Println("client temp msg2 err:", err)
		return
	}

	//将sendData1,和 sendData2 拼接一起,组成粘包
	sendData1 = append(sendData1, sendData2...)

	//向服务器端写数据
	conn.Write(sendData1)

	//客户端阻塞
	select {}
}


================================================
FILE: examples/zinx_version_ex/datapackDemo/server/server.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/zpack"
	"io"
	"net"
)

// 只是负责测试datapack拆包,封包功能
func main() {
	//创建socket TCP Server
	listener, err := net.Listen("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println("server listen err:", err)
		return
	}

	//创建服务器gotoutine,负责从客户端goroutine读取粘包的数据,然后进行解析

	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("server accept err:", err)
		}

		//处理客户端请求
		go func(conn net.Conn) {
			//创建封包拆包对象dp
			dp := zpack.NewDataPack()
			for {
				//1 先读出流中的head部分
				headData := make([]byte, dp.GetHeadLen())
				_, err := io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
				if err != nil {
					fmt.Println("read head error")
					break
				}
				//将headData字节流 拆包到msg中
				msgHead, err := dp.Unpack(headData)
				if err != nil {
					fmt.Println("server unpack err:", err)
					return
				}

				if msgHead.GetDataLen() > 0 {
					//msg 是有data数据的,需要再次读取data数据
					msg := msgHead.(*zpack.Message)
					msg.Data = make([]byte, msg.GetDataLen())

					//根据dataLen从io中读取字节流
					_, err := io.ReadFull(conn, msg.Data)
					if err != nil {
						fmt.Println("server unpack data err:", err)
						return
					}

					fmt.Println("==> Recv Msg: ID=", msg.ID, ", len=", msg.DataLen, ", data=", string(msg.Data))
				}
			}
		}(conn)
	}

	//阻塞
	select {}
}


================================================
FILE: examples/zinx_version_ex/protoDemo/main.go
================================================
package main

import (
	"encoding/hex"
	"fmt"
	"github.com/aceld/zinx/examples/zinx_version_ex/protoDemo/pb"
	"github.com/golang/protobuf/proto"
)

func main() {
	person := &pb.Person{
		Name:   "XiaoYuer",
		Age:    16,
		Emails: []string{"xiao_yu_er@sina.com", "yu_er@sina.cn"},
		Phones: []*pb.PhoneNumber{
			{
				Number: "13113111311",
				Type:   pb.PhoneType_MOBILE,
			},
			{
				Number: "14141444144",
				Type:   pb.PhoneType_HOME,
			},
			{
				Number: "19191919191",
				Type:   pb.PhoneType_WORK,
			},
		},
	}

	data, err := proto.Marshal(person)
	if err != nil {
		fmt.Println("marshal err:", err)
	}

	fmt.Println(hex.EncodeToString(data))

	newdata := &pb.Person{}
	err = proto.Unmarshal(data, newdata)
	if err != nil {
		fmt.Println("unmarshal err:", err)
	}
	fmt.Println(newdata)
}


================================================
FILE: examples/zinx_version_ex/protoDemo/pb/Person.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: Person.proto

package pb

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// enum为关键字,作用为定义一种枚举类型
type PhoneType int32

const (
	PhoneType_MOBILE PhoneType = 0
	PhoneType_HOME   PhoneType = 1
	PhoneType_WORK   PhoneType = 2
)

var PhoneType_name = map[int32]string{
	0: "MOBILE",
	1: "HOME",
	2: "WORK",
}

var PhoneType_value = map[string]int32{
	"MOBILE": 0,
	"HOME":   1,
	"WORK":   2,
}

func (x PhoneType) String() string {
	return proto.EnumName(PhoneType_name, int32(x))
}

func (PhoneType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_841ab6396175eaf3, []int{0}
}

// message为关键字,作用为定义一种消息类型
type Person struct {
	Name                 string         `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Age                  int32          `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
	Emails               []string       `protobuf:"bytes,3,rep,name=emails,proto3" json:"emails,omitempty"`
	Phones               []*PhoneNumber `protobuf:"bytes,4,rep,name=phones,proto3" json:"phones,omitempty"`
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
	XXX_unrecognized     []byte         `json:"-"`
	XXX_sizecache        int32          `json:"-"`
}

func (m *Person) Reset()         { *m = Person{} }
func (m *Person) String() string { return proto.CompactTextString(m) }
func (*Person) ProtoMessage()    {}
func (*Person) Descriptor() ([]byte, []int) {
	return fileDescriptor_841ab6396175eaf3, []int{0}
}

func (m *Person) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Person.Unmarshal(m, b)
}
func (m *Person) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Person.Marshal(b, m, deterministic)
}
func (m *Person) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Person.Merge(m, src)
}
func (m *Person) XXX_Size() int {
	return xxx_messageInfo_Person.Size(m)
}
func (m *Person) XXX_DiscardUnknown() {
	xxx_messageInfo_Person.DiscardUnknown(m)
}

var xxx_messageInfo_Person proto.InternalMessageInfo

func (m *Person) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *Person) GetAge() int32 {
	if m != nil {
		return m.Age
	}
	return 0
}

func (m *Person) GetEmails() []string {
	if m != nil {
		return m.Emails
	}
	return nil
}

func (m *Person) GetPhones() []*PhoneNumber {
	if m != nil {
		return m.Phones
	}
	return nil
}

// message为关键字,作用为定义一种消息类型可以被另外的消息类型嵌套使用
type PhoneNumber struct {
	Number               string    `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"`
	Type                 PhoneType `protobuf:"varint,2,opt,name=type,proto3,enum=pb.PhoneType" json:"type,omitempty"`
	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
	XXX_unrecognized     []byte    `json:"-"`
	XXX_sizecache        int32     `json:"-"`
}

func (m *PhoneNumber) Reset()         { *m = PhoneNumber{} }
func (m *PhoneNumber) String() string { return proto.CompactTextString(m) }
func (*PhoneNumber) ProtoMessage()    {}
func (*PhoneNumber) Descriptor() ([]byte, []int) {
	return fileDescriptor_841ab6396175eaf3, []int{1}
}

func (m *PhoneNumber) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_PhoneNumber.Unmarshal(m, b)
}
func (m *PhoneNumber) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_PhoneNumber.Marshal(b, m, deterministic)
}
func (m *PhoneNumber) XXX_Merge(src proto.Message) {
	xxx_messageInfo_PhoneNumber.Merge(m, src)
}
func (m *PhoneNumber) XXX_Size() int {
	return xxx_messageInfo_PhoneNumber.Size(m)
}
func (m *PhoneNumber) XXX_DiscardUnknown() {
	xxx_messageInfo_PhoneNumber.DiscardUnknown(m)
}

var xxx_messageInfo_PhoneNumber proto.InternalMessageInfo

func (m *PhoneNumber) GetNumber() string {
	if m != nil {
		return m.Number
	}
	return ""
}

func (m *PhoneNumber) GetType() PhoneType {
	if m != nil {
		return m.Type
	}
	return PhoneType_MOBILE
}

func init() {
	proto.RegisterEnum("pb.PhoneType", PhoneType_name, PhoneType_value)
	proto.RegisterType((*Person)(nil), "pb.Person")
	proto.RegisterType((*PhoneNumber)(nil), "pb.PhoneNumber")
}

func init() { proto.RegisterFile("Person.proto", fileDescriptor_841ab6396175eaf3) }

var fileDescriptor_841ab6396175eaf3 = []byte{
	// 209 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0xcd, 0x4a, 0xc4, 0x30,
	0x14, 0x85, 0x4d, 0x13, 0x83, 0xbd, 0xe3, 0x4f, 0xb8, 0x0b, 0xc9, 0x32, 0xce, 0xc6, 0xa0, 0xd0,
	0xc5, 0xf8, 0x06, 0xc2, 0xc0, 0x88, 0x8e, 0x1d, 0x82, 0xe0, 0xba, 0x81, 0xa0, 0x82, 0x4d, 0x42,
	0x3b, 0x2e, 0xfa, 0xf6, 0x92, 0x34, 0x94, 0xd9, 0x7d, 0xf7, 0x3b, 0x70, 0x0e, 0x17, 0x2e, 0x0f,
	0x6e, 0x18, 0x83, 0x6f, 0xe2, 0x10, 0x8e, 0x01, 0xab, 0x68, 0xd7, 0x01, 0xf8, 0xec, 0x10, 0x81,
	0xf9, 0xae, 0x77, 0x92, 0x28, 0xa2, 0x6b, 0x93, 0x19, 0x05, 0xd0, 0xee, 0xcb, 0xc9, 0x4a, 0x11,
	0x7d, 0x6e, 0x12, 0xe2, 0x2d, 0x70, 0xd7, 0x77, 0x3f, 0xbf, 0xa3, 0xa4, 0x8a, 0xea, 0xda, 0x94,
	0x0b, 0xef, 0x81, 0xc7, 0xef, 0xe0, 0xdd, 0x28, 0x99, 0xa2, 0x7a, 0xb5, 0xb9, 0x69, 0xa2, 0x6d,
	0x0e, 0xc9, 0xbc, 0xff, 0xf5, 0xd6, 0x0d, 0xa6, 0xc4, 0xeb, 0x1d, 0xac, 0x4e, 0x74, 0xea, 0xf3,
	0x99, 0xca, 0x6e, 0xb9, 0xf0, 0x0e, 0xd8, 0x71, 0x8a, 0xf3, 0xf4, 0xf5, 0xe6, 0x6a, 0x69, 0xfb,
	0x98, 0xa2, 0x33, 0x39, 0x7a, 0x78, 0x84, 0x7a, 0x51, 0x08, 0xc0, 0xf7, 0xed, 0xf3, 0xcb, 0xdb,
	0x56, 0x9c, 0xe1, 0x05, 0xb0, 0x5d, 0xbb, 0xdf, 0x0a, 0x92, 0xe8, 0xb3, 0x35, 0xaf, 0xa2, 0xb2,
	0x3c, 0xbf, 0xfc, 0xf4, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x3c, 0xf1, 0xb8, 0x02, 0x01, 0x00,
	0x00,
}


================================================
FILE: examples/zinx_version_ex/protoDemo/pb/Person.proto
================================================
syntax = "proto3"; 						//指定版本信息,不指定会报错
package pb;						//后期生成go文件的包名

//message为关键字,作用为定义一种消息类型
message Person {
	string	name = 1;					//姓名
    int32	age = 2;					//年龄
	repeated string emails = 3; 		//电子邮件(repeated表示字段允许重复)
	repeated PhoneNumber phones = 4;	//手机号
}

//enum为关键字,作用为定义一种枚举类型
enum PhoneType {
	MOBILE = 0;
    HOME = 1;
    WORK = 2;
}

//message为关键字,作用为定义一种消息类型可以被另外的消息类型嵌套使用
message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
}

================================================
FILE: examples/zinx_websocket/client/client.go
================================================
package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

type PositionClientRouter struct {
	znet.BaseRouter
}

func (this *PositionClientRouter) Handle(request ziface.IRequest) {

}

// 客户端自定义业务
func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(1, []byte("ping ping ping ..."))
		if err != nil {
			fmt.Println(err)

		}
		time.Sleep(1 * time.Second)
	}
}

// 创建连接的时候执行
func DoClientConnectedBegin(conn ziface.IConnection) {
	//设置两个连接属性,在连接创建之后
	conn.SetProperty("Name", "刘丹冰")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func wait() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
}

func main() {
	// Create a Client.
	client := znet.NewWsClient("127.0.0.1", 9000)

	// Add business logic for when the connection is first established.(添加首次建立连接时的业务)
	client.SetOnConnStart(DoClientConnectedBegin)
	// Register business routing for receiving messages from the server.(注册收到服务器消息业务路由)
	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})
	// Start the client.
	client.Start()
	select {
	case err := <-client.GetErrChan():
		// Handle the errors returned by the client.(处理客户端返回的错误)
		zlog.Ins().ErrorF("client err:%v", err)
	}

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
	// Clean up the client.(清理客户端)
	client.Stop()
	time.Sleep(time.Second * 2)
}


================================================
FILE: examples/zinx_websocket/minicode/.eslintrc.js
================================================
/*
 * Eslint config file
 * Documentation: https://eslint.org/docs/user-guide/configuring/
 * Install the Eslint extension before using this feature.
 */
module.exports = {
  env: {
    es6: true,
    browser: true,
    node: true,
  },
  ecmaFeatures: {
    modules: true,
  },
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: 'module',
  },
  globals: {
    wx: true,
    App: true,
    Page: true,
    getCurrentPages: true,
    getApp: true,
    Component: true,
    requirePlugin: true,
    requireMiniProgram: true,
  },
  // extends: 'eslint:recommended',
  rules: {},
}


================================================
FILE: examples/zinx_websocket/minicode/app.js
================================================
const Buffer = require("buffer").Buffer;
App({
    onLaunch() {
        const socket = wx.connectSocket({
            url: 'ws://localhost:9000',
            protocols:["12321","321321321",32132121]
        })
        wx.onSocketOpen((result) => {
            console.log("连接成功")
            wx.sendSocketMessage({
                data: this.encodeTLV(1, "hello"),


            })
        })
        socket.onMessage(result => {
            let message = this.decodeTLV(result.data)
            console.log(message)
        })
    },

    globalData: {
        TYPE_LENGTH: 4,
        LENGTH_LENGTH: 4,
    },
    // 将数据编码为 TLV 格式
    encodeTLV(type, value) {
        const length = value.length;
        const typeBuffer = Buffer.alloc(this.globalData.TYPE_LENGTH);
        const lengthBuffer = Buffer.alloc(this.globalData.LENGTH_LENGTH);
        const valueBuffer = Buffer.from(value);
        typeBuffer.writeUInt32BE(type, 0);
        lengthBuffer.writeUInt32BE(length, 0);
        return Buffer.concat([typeBuffer, lengthBuffer, valueBuffer], this.globalData.TYPE_LENGTH + this.globalData.LENGTH_LENGTH + length);
    },

    // 从 TLV 格式解码数据
    decodeTLV(buffer) {
        // 解析包头长度
        let data = Buffer.from(buffer)
        const tag = Buffer.alloc(this.globalData.TYPE_LENGTH);
        let offset = 0;
        data.copy(tag, 0, offset, 4)
        const dataLen = Buffer.alloc(this.globalData.LENGTH_LENGTH);
        offset += 4;
        data.copy(dataLen, 0, offset, offset + 4)
        // 解析数据包内容
        const body = new Buffer(dataLen.readInt32BE())
        offset += 4
        data.copy(body, 0, offset, offset + dataLen.readInt32BE());
        let message = {
            tag: tag.readUInt32BE(),
            dataLen: dataLen.readUInt32BE(),
            data: body
        }
        return message
    }
})

================================================
FILE: examples/zinx_websocket/minicode/app.json
================================================
{
  "pages": [
    "index/index"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle": "black"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents"
}


================================================
FILE: examples/zinx_websocket/minicode/app.wxss
================================================


================================================
FILE: examples/zinx_websocket/minicode/index/index.js
================================================
const app = getApp()

Page({
  data: {

  },
  onLoad() {
    console.log('代码片段是一种迷你、可分享的小程序或小游戏项目,可用于分享小程序和小游戏的开发经验、展示组件和 API 的使用、复现开发问题和 Bug 等。可点击以下连接查看代码片段的详细文档:')
    console.log('https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/devtools.html')
  },
})


================================================
FILE: examples/zinx_websocket/minicode/index/index.json
================================================
{
  "usingComponents": {}
}

================================================
FILE: examples/zinx_websocket/minicode/index/index.wxml
================================================
<view class="intro">欢迎使用代码片段,可在控制台查看代码片段的说明和文档</view>

================================================
FILE: examples/zinx_websocket/minicode/index/index.wxss
================================================
.intro {
  margin: 30px;
  text-align: center;
}

================================================
FILE: examples/zinx_websocket/minicode/package.json
================================================
{
  "dependencies": {
    "buffer": "^6.0.3"
  }
}


================================================
FILE: examples/zinx_websocket/minicode/project.config.json
================================================
{
    "appid": "wx0b3c079df9f406b6",
    "compileType": "miniprogram",
    "libVersion": "2.30.4",
    "packOptions": {
        "ignore": [],
        "include": []
    },
    "setting": {
        "coverView": true,
        "es6": true,
        "postcss": true,
        "minified": true,
        "enhance": true,
        "showShadowRootInWxmlPanel": true,
        "packNpmRelationList": [],
        "babelSetting": {
            "ignore": [],
            "disablePlugins": [],
            "outputPath": ""
        },
        "condition": false
    },
    "condition": {},
    "editorSetting": {
        "tabIndent": "insertSpaces",
        "tabSize": 4
    }
}

================================================
FILE: examples/zinx_websocket/minicode/project.private.config.json
================================================
{
    "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
    "projectname": "minicode-15",
    "setting": {
        "compileHotReLoad": true,
        "urlCheck": false
    }
}

================================================
FILE: examples/zinx_websocket/minicode/sitemap.json
================================================
{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [{
  "action": "allow",
  "page": "*"
  }]
}

================================================
FILE: examples/zinx_websocket/server/server.go
================================================
package main

import (
	"github.com/aceld/zinx/examples/zinx_server/s_router"
	"github.com/aceld/zinx/zconf"
	"github.com/aceld/zinx/znet"
)

func main() {
	// Set up as WebSocket before starting. (在启动之前设置为 websocket)
	zconf.GlobalObject.Mode = ""
	zconf.GlobalObject.LogFile = ""

	s := znet.NewServer()

	s.AddRouter(100, &s_router.PingRouter{})
	s.AddRouter(1, &s_router.HelloZinxRouter{})

	s.Serve()
}


================================================
FILE: go.mod
================================================
module github.com/aceld/zinx

go 1.23.0

require (
	github.com/gorilla/websocket v1.5.0
	github.com/stretchr/testify v1.8.1
	github.com/xtaci/kcp-go v5.4.20+incompatible
	golang.org/x/net v0.38.0 // indirect
	google.golang.org/protobuf v1.33.0 // indirect
)

require github.com/golang/protobuf v1.5.0

require (
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/klauspost/cpuid/v2 v2.1.1 // indirect
	github.com/klauspost/reedsolomon v1.11.8 // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
	github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
	github.com/tjfoc/gmsm v1.4.1 // indirect
	github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 // indirect
	golang.org/x/crypto v0.36.0 // indirect
	golang.org/x/sys v0.31.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)


================================================
FILE: go.sum
================================================
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0=
github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY=
github.com/klauspost/reedsolomon v1.11.8/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60
Download .txt
gitextract_ynwx33qg/

├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── reviewdog.yml
├── .gitignore
├── .golangci.yaml
├── LICENSE
├── Makefile
├── README-CN.md
├── README.md
├── examples/
│   ├── zinx_RequestPollMode/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── no_pool_mode_server/
│   │   │   └── NoPoolModeServer.go
│   │   └── pool_mode_server/
│   │       └── PoolModeServer.go
│   ├── zinx_async_op/
│   │   ├── async_op_apis/
│   │   │   └── user_async_api.go
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── db_model/
│   │   │   └── user_dao.go
│   │   ├── msg_struct/
│   │   │   └── user_login.go
│   │   ├── router/
│   │   │   └── login.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_client/
│   │   ├── Makefile
│   │   ├── build.sh
│   │   ├── c_router/
│   │   │   ├── hello.go
│   │   │   └── ping.go
│   │   ├── main.go
│   │   └── version
│   ├── zinx_client_old/
│   │   ├── Makefile
│   │   ├── build.sh
│   │   ├── c_router/
│   │   │   ├── hello.go
│   │   │   └── ping.go
│   │   ├── main.go
│   │   └── version
│   ├── zinx_closecallback/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── router/
│   │   │   └── ping_router.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_decoder/
│   │   ├── README.MD
│   │   ├── bili/
│   │   │   ├── README.MD
│   │   │   ├── main.go
│   │   │   └── router/
│   │   │       ├── bili0x10router.go
│   │   │       ├── bili0x13router.go
│   │   │       ├── bili0x14router.go
│   │   │       ├── bili0x15router.go
│   │   │       └── bili0x16router.go
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── router/
│   │   │   ├── htlvcrcbusinessrouter.go
│   │   │   └── tlvbusinessrouter.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_dynamic_bind/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server.go
│   ├── zinx_heartbeat/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── client_default/
│   │   │   └── client_default.go
│   │   ├── server/
│   │   │   ├── conf/
│   │   │   │   └── zinx.json
│   │   │   └── server.go
│   │   └── server_default/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server_default.go
│   ├── zinx_interceptor/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── interceptors/
│   │   │   └── interceptor_1.go
│   │   ├── router/
│   │   │   └── route.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_kcp/
│   │   ├── client/
│   │   │   └── kcp_client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_logger/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       ├── my_logger.go
│   │       └── server.go
│   ├── zinx_metrics/
│   │   ├── client/
│   │   │   ├── c1/
│   │   │   │   └── client.go
│   │   │   └── c2/
│   │   │       └── client.go
│   │   └── server/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server.go
│   ├── zinx_mutiport/
│   │   ├── client8999/
│   │   │   └── client.go
│   │   ├── client9000/
│   │   │   └── client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_new_router/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       ├── conf/
│   │       │   └── zinx.json
│   │       └── server.go
│   ├── zinx_protobuf/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_routerSlices/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── default_func_server/
│   │   │   └── server.go
│   │   ├── router_func_server/
│   │   │   └── server.go
│   │   └── router_group_server/
│   │       └── server.go
│   ├── zinx_server/
│   │   ├── Makefile
│   │   ├── build.sh
│   │   ├── conf/
│   │   │   └── zinx.json
│   │   ├── dockerfile
│   │   ├── main.go
│   │   ├── s_router/
│   │   │   ├── hello.go
│   │   │   └── ping.go
│   │   └── version
│   ├── zinx_tls/
│   │   ├── client/
│   │   │   └── client.go
│   │   └── server/
│   │       └── server.go
│   ├── zinx_version_ex/
│   │   ├── ZinxV0.10Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.11Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.1Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   ├── ZinxV0.2Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   ├── ZinxV0.3Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   ├── ZinxV0.4Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       ├── conf/
│   │   │       │   └── zinx.json
│   │   │       └── server.go
│   │   ├── ZinxV0.5Test/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       ├── conf/
│   │   │       │   └── zinx.json
│   │   │       └── server.go
│   │   ├── ZinxV0.6Test-V0.7Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.8Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── ZinxV0.9Test/
│   │   │   ├── client0/
│   │   │   │   └── Client0.go
│   │   │   ├── client1/
│   │   │   │   └── Client1.go
│   │   │   └── server/
│   │   │       ├── Server.go
│   │   │       └── conf/
│   │   │           └── zinx.json
│   │   ├── datapackDemo/
│   │   │   ├── client/
│   │   │   │   └── client.go
│   │   │   └── server/
│   │   │       └── server.go
│   │   └── protoDemo/
│   │       ├── main.go
│   │       └── pb/
│   │           ├── Person.pb.go
│   │           └── Person.proto
│   └── zinx_websocket/
│       ├── client/
│       │   └── client.go
│       ├── minicode/
│       │   ├── .eslintrc.js
│       │   ├── app.js
│       │   ├── app.json
│       │   ├── app.wxss
│       │   ├── index/
│       │   │   ├── index.js
│       │   │   ├── index.json
│       │   │   ├── index.wxml
│       │   │   └── index.wxss
│       │   ├── package.json
│       │   ├── project.config.json
│       │   ├── project.private.config.json
│       │   └── sitemap.json
│       └── server/
│           └── server.go
├── go.mod
├── go.sum
├── logo/
│   └── zinxlogo.go
├── zasync_op/
│   ├── async_op.go
│   ├── async_op_result.go
│   └── async_worker.go
├── zconf/
│   ├── env.go
│   ├── userconf.go
│   └── zconf.go
├── zdecoder/
│   ├── crc.go
│   ├── htlvcrcdecoder.go
│   ├── ltvdecoder_little.go
│   └── tlvdecoder.go
├── ziface/
│   ├── iclient.go
│   ├── iconnection.go
│   ├── iconnmanager.go
│   ├── idatapack.go
│   ├── idecoder.go
│   ├── iheartbeat.go
│   ├── iinterceptor.go
│   ├── ilengthfield.go
│   ├── ilogger.go
│   ├── imessage.go
│   ├── imsghandler.go
│   ├── inotify.go
│   ├── irequest.go
│   ├── irouter.go
│   ├── iserver.go
│   └── options.go
├── zinterceptor/
│   ├── chain.go
│   ├── framedecoder.go
│   └── interceptor.go
├── zinx_app_demo/
│   └── mmo_game/
│       ├── README-CN.md
│       ├── README.md
│       ├── api/
│       │   ├── move.go
│       │   └── world_chat.go
│       ├── client_AI_robot.go
│       ├── conf/
│       │   └── zinx.json
│       ├── core/
│       │   ├── aoi.go
│       │   ├── aoi_test.go
│       │   ├── grid.go
│       │   ├── player.go
│       │   └── world_manager.go
│       ├── pb/
│       │   ├── build.sh
│       │   ├── msg.pb.go
│       │   └── msg.proto
│       └── server.go
├── zlog/
│   ├── default.go
│   ├── logger_core.go
│   ├── stdzlog.go
│   └── zlog_test.go
├── znet/
│   ├── acceptdelay.go
│   ├── acceptdelay_test.go
│   ├── callbacks.go
│   ├── callbacks_test.go
│   ├── chainbuilder.go
│   ├── client.go
│   ├── connection.go
│   ├── connmanager.go
│   ├── defaultrouterfunc.go
│   ├── heartbeat.go
│   ├── kcp_connection.go
│   ├── msghandler.go
│   ├── options.go
│   ├── request.go
│   ├── request_func.go
│   ├── router.go
│   ├── routerSilces_test.go
│   ├── server.go
│   ├── server_test.go
│   └── ws_connection.go
├── znotify/
│   ├── notify.go
│   └── notify_test.go
├── zpack/
│   ├── datapack_ltv_littleendian.go
│   ├── datapack_tlv_bigendian.go
│   ├── datapack_tlv_bigendian_test.go
│   ├── message.go
│   └── packfactory.go
├── ztimer/
│   ├── delayfunc.go
│   ├── delayfunc_test.go
│   ├── timer.go
│   ├── timer_test.go
│   ├── timerscheduler.go
│   ├── timerscheduler_test.go
│   ├── timewheel.go
│   └── timewheel_test.go
└── zutils/
    ├── hash.go
    ├── shard_lock_map.go
    ├── shard_lock_map_bench_test.go
    ├── shard_lock_map_test.go
    ├── snowflake_uuid.go
    ├── snowflake_uuid_test.go
    └── witer.go
Download .txt
SYMBOL INDEX (1240 symbols across 180 files)

FILE: examples/zinx_RequestPollMode/client/client.go
  function business (line 16) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 37) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 48) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 62) | func main() {

FILE: examples/zinx_RequestPollMode/no_pool_mode_server/NoPoolModeServer.go
  function NoPoll1 (line 14) | func NoPoll1(request ziface.IRequest) {
  function NoPoll2 (line 19) | func NoPoll2(request ziface.IRequest) {
  function NoPoll4 (line 26) | func NoPoll4(request ziface.IRequest) {
  function main (line 31) | func main() {

FILE: examples/zinx_RequestPollMode/pool_mode_server/PoolModeServer.go
  function Poll1 (line 12) | func Poll1(request ziface.IRequest) {
  function Poll2 (line 26) | func Poll2(request ziface.IRequest) {
  function Poll3 (line 46) | func Poll3(request ziface.IRequest) {
  function Poll4 (line 54) | func Poll4(request ziface.IRequest) {
  function main (line 59) | func main() {

FILE: examples/zinx_async_op/async_op_apis/user_async_api.go
  function AsyncUserSaveData (line 9) | func AsyncUserSaveData(request ziface.IRequest) *zasync_op.AsyncOpResult {

FILE: examples/zinx_async_op/client/client.go
  function main (line 11) | func main() {

FILE: examples/zinx_async_op/db_model/user_dao.go
  type UserModel (line 9) | type UserModel struct
  function SaveUserData (line 15) | func SaveUserData() *UserModel {

FILE: examples/zinx_async_op/msg_struct/user_login.go
  type MsgLoginResponse (line 3) | type MsgLoginResponse struct

FILE: examples/zinx_async_op/router/login.go
  type LoginRouter (line 15) | type LoginRouter struct
    method Handle (line 19) | func (hr *LoginRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_async_op/server/server.go
  function OnConnectionAdd (line 10) | func OnConnectionAdd(conn ziface.IConnection) {
  function OnConnectionLost (line 14) | func OnConnectionLost(conn ziface.IConnection) {
  function main (line 18) | func main() {

FILE: examples/zinx_client/c_router/hello.go
  type HelloRouter (line 9) | type HelloRouter struct
    method Handle (line 14) | func (this *HelloRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_client/c_router/ping.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_client/main.go
  function business (line 21) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 36) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 47) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 61) | func main() {

FILE: examples/zinx_client_old/c_router/hello.go
  type HelloRouter (line 9) | type HelloRouter struct
    method Handle (line 14) | func (this *HelloRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_client_old/c_router/ping.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_client_old/main.go
  function main (line 17) | func main() {

FILE: examples/zinx_closecallback/client/client.go
  function business (line 16) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 34) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 54) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 58) | func main() {

FILE: examples/zinx_closecallback/router/ping_router.go
  type PingRouter (line 12) | type PingRouter struct
    method PreHandle (line 18) | func (r *PingRouter) PreHandle(req ziface.IRequest) {
    method Handle (line 23) | func (r *PingRouter) Handle(req ziface.IRequest) {
    method PostHandle (line 32) | func (r *PingRouter) PostHandle(req ziface.IRequest) {

FILE: examples/zinx_closecallback/server/server.go
  function DoConnectionBegin (line 14) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 41) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 45) | func main() {

FILE: examples/zinx_decoder/bili/main.go
  function DoConnectionBegin (line 10) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 13) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 16) | func main() {

FILE: examples/zinx_decoder/bili/router/bili0x10router.go
  type Data0x10Router (line 12) | type Data0x10Router struct
    method Handle (line 16) | func (this *Data0x10Router) Handle(request ziface.IRequest) {
  function pack10 (line 34) | func pack10(_data zdecoder.HtlvCrcDecoder) []byte {

FILE: examples/zinx_decoder/bili/router/bili0x13router.go
  type Data0x13Router (line 11) | type Data0x13Router struct
    method Handle (line 15) | func (this *Data0x13Router) Handle(request ziface.IRequest) {
  function pack13 (line 33) | func pack13(_data zdecoder.HtlvCrcDecoder) []byte {

FILE: examples/zinx_decoder/bili/router/bili0x14router.go
  type Data0x14Router (line 11) | type Data0x14Router struct
    method Handle (line 15) | func (this *Data0x14Router) Handle(request ziface.IRequest) {
  function pack14 (line 33) | func pack14(_data zdecoder.HtlvCrcDecoder) []byte {

FILE: examples/zinx_decoder/bili/router/bili0x15router.go
  type Data0x15Router (line 11) | type Data0x15Router struct
    method Handle (line 15) | func (this *Data0x15Router) Handle(request ziface.IRequest) {
  function pack15 (line 33) | func pack15(_data zdecoder.HtlvCrcDecoder) []byte {

FILE: examples/zinx_decoder/bili/router/bili0x16router.go
  type Data0x16Router (line 11) | type Data0x16Router struct
    method Handle (line 15) | func (this *Data0x16Router) Handle(request ziface.IRequest) {
  function pack16 (line 35) | func pack16(_data zdecoder.HtlvCrcDecoder) []byte {

FILE: examples/zinx_decoder/client/client.go
  function getTLVPackData (line 17) | func getTLVPackData() []byte {
  function getTLVData (line 36) | func getTLVData(index int) []byte {
  function getHTLVCRCData (line 61) | func getHTLVCRCData(index int) []byte {
  function business (line 86) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 97) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function main (line 102) | func main() {

FILE: examples/zinx_decoder/router/htlvcrcbusinessrouter.go
  type HtlvCrcBusinessRouter (line 11) | type HtlvCrcBusinessRouter struct
    method Handle (line 15) | func (this *HtlvCrcBusinessRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_decoder/router/tlvbusinessrouter.go
  type TLVBusinessRouter (line 10) | type TLVBusinessRouter struct
    method Handle (line 14) | func (this *TLVBusinessRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_decoder/server/server.go
  function DoConnectionBegin (line 11) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 15) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 19) | func main() {

FILE: examples/zinx_dynamic_bind/client/client.go
  constant PingType (line 14) | PingType = 1
  constant PongType (line 15) | PongType = 2
  type PongRouter (line 19) | type PongRouter struct
    method Handle (line 26) | func (p *PongRouter) Handle(request ziface.IRequest) {
  function onClient1Start (line 32) | func onClient1Start(conn ziface.IConnection) {
  function onClient2Start (line 41) | func onClient2Start(conn ziface.IConnection) {
  function onClient3Start (line 50) | func onClient3Start(conn ziface.IConnection) {
  function main (line 59) | func main() {

FILE: examples/zinx_dynamic_bind/server/server.go
  function OnConnectionAdd (line 12) | func OnConnectionAdd(conn ziface.IConnection) {
  function OnConnectionLost (line 16) | func OnConnectionLost(conn ziface.IConnection) {
  type blockRouter (line 20) | type blockRouter struct
    method Handle (line 27) | func (r *blockRouter) Handle(request ziface.IRequest) {
  function main (line 49) | func main() {

FILE: examples/zinx_heartbeat/client/client.go
  function myClientHeartBeatMsg (line 12) | func myClientHeartBeatMsg(conn ziface.IConnection) []byte {
  function myClientOnRemoteNotAlive (line 18) | func myClientOnRemoteNotAlive(conn ziface.IConnection) {
  type myClientHeartBeatRouter (line 25) | type myClientHeartBeatRouter struct
    method Handle (line 29) | func (r *myClientHeartBeatRouter) Handle(request ziface.IRequest) {
  function main (line 33) | func main() {

FILE: examples/zinx_heartbeat/client_default/client_default.go
  function main (line 9) | func main() {

FILE: examples/zinx_heartbeat/server/server.go
  function myHeartBeatMsg (line 12) | func myHeartBeatMsg(conn ziface.IConnection) []byte {
  function myOnRemoteNotAlive (line 18) | func myOnRemoteNotAlive(conn ziface.IConnection) {
  type myHeartBeatRouter (line 25) | type myHeartBeatRouter struct
    method Handle (line 29) | func (r *myHeartBeatRouter) Handle(request ziface.IRequest) {
  function main (line 33) | func main() {

FILE: examples/zinx_heartbeat/server_default/server_default.go
  function main (line 8) | func main() {

FILE: examples/zinx_interceptor/client/client.go
  function main (line 10) | func main() {

FILE: examples/zinx_interceptor/interceptors/interceptor_1.go
  type MyInterceptor (line 10) | type MyInterceptor struct
    method Intercept (line 12) | func (m *MyInterceptor) Intercept(chain ziface.IChain) ziface.IcResp {

FILE: examples/zinx_interceptor/router/route.go
  type HelloRouter (line 9) | type HelloRouter struct
    method Handle (line 13) | func (hr *HelloRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_interceptor/server/server.go
  function main (line 9) | func main() {

FILE: examples/zinx_kcp/client/kcp_client.go
  function main (line 13) | func main() {

FILE: examples/zinx_kcp/server/server.go
  type TestRouter (line 13) | type TestRouter struct
    method PreHandle (line 20) | func (t *TestRouter) PreHandle(req ziface.IRequest) {
    method Handle (line 32) | func (t *TestRouter) Handle(req ziface.IRequest) {
    method PostHandle (line 57) | func (t *TestRouter) PostHandle(req ziface.IRequest) {
  function Err (line 64) | func Err() error {
  function main (line 69) | func main() {

FILE: examples/zinx_logger/client/client.go
  function business (line 14) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 28) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 37) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 49) | func main() {

FILE: examples/zinx_logger/server/my_logger.go
  type MyLogger (line 14) | type MyLogger struct
    method InfoF (line 17) | func (l *MyLogger) InfoF(format string, v ...interface{}) {
    method ErrorF (line 21) | func (l *MyLogger) ErrorF(format string, v ...interface{}) {
    method DebugF (line 25) | func (l *MyLogger) DebugF(format string, v ...interface{}) {
    method InfoFX (line 30) | func (l *MyLogger) InfoFX(ctx context.Context, format string, v ...int...
    method ErrorFX (line 35) | func (l *MyLogger) ErrorFX(ctx context.Context, format string, v ...in...
    method DebugFX (line 40) | func (l *MyLogger) DebugFX(ctx context.Context, format string, v ...in...

FILE: examples/zinx_logger/server/server.go
  type TestRouter (line 12) | type TestRouter struct
    method PreHandle (line 17) | func (t *TestRouter) PreHandle(req ziface.IRequest) {
    method Handle (line 29) | func (t *TestRouter) Handle(req ziface.IRequest) {
    method PostHandle (line 38) | func (t *TestRouter) PostHandle(req ziface.IRequest) {
  function main (line 45) | func main() {

FILE: examples/zinx_metrics/client/c1/client.go
  function business (line 14) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 28) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 38) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 50) | func main() {

FILE: examples/zinx_metrics/client/c2/client.go
  function business (line 14) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 28) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 37) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 49) | func main() {

FILE: examples/zinx_metrics/server/server.go
  function DoConnectionBegin (line 10) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 22) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 36) | func main() {

FILE: examples/zinx_mutiport/client8999/client.go
  function business (line 14) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 28) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 38) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 50) | func main() {

FILE: examples/zinx_mutiport/client9000/client.go
  function business (line 14) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 28) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function DoClientConnectedLost (line 37) | func DoClientConnectedLost(conn ziface.IConnection) {
  function main (line 49) | func main() {

FILE: examples/zinx_mutiport/server/server.go
  function DoConnectionBegin (line 15) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 29) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 43) | func main() {

FILE: examples/zinx_new_router/client/client.go
  function main (line 13) | func main() {

FILE: examples/zinx_new_router/server/server.go
  type TestRouter (line 11) | type TestRouter struct
    method PreHandle (line 16) | func (t *TestRouter) PreHandle(req ziface.IRequest) {
    method Handle (line 28) | func (t *TestRouter) Handle(req ziface.IRequest) {
    method PostHandle (line 56) | func (t *TestRouter) PostHandle(req ziface.IRequest) {
  function Err (line 63) | func Err() error {
  function main (line 68) | func main() {

FILE: examples/zinx_protobuf/client/client.go
  type PositionClientRouter (line 14) | type PositionClientRouter struct
    method Handle (line 18) | func (this *PositionClientRouter) Handle(request ziface.IRequest) {
  function business (line 32) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 58) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function wait (line 65) | func wait() {
  function main (line 72) | func main() {

FILE: examples/zinx_protobuf/server/server.go
  type PositionServerRouter (line 13) | type PositionServerRouter struct
    method Handle (line 18) | func (this *PositionServerRouter) Handle(request ziface.IRequest) {
  function main (line 47) | func main() {

FILE: examples/zinx_routerSlices/client/client.go
  function main (line 9) | func main() {

FILE: examples/zinx_routerSlices/default_func_server/server.go
  function DefaultTest1 (line 11) | func DefaultTest1(request ziface.IRequest) {
  function DefaultTest2 (line 14) | func DefaultTest2(request ziface.IRequest) {
  function main (line 20) | func main() {

FILE: examples/zinx_routerSlices/router_func_server/server.go
  function Auth1 (line 10) | func Auth1(request ziface.IRequest) {
  function Auth2 (line 20) | func Auth2(request ziface.IRequest) {
  function Auth3 (line 29) | func Auth3(request ziface.IRequest) {
  function TestFunc (line 35) | func TestFunc(request ziface.IRequest) {
  function main (line 39) | func main() {

FILE: examples/zinx_routerSlices/router_group_server/server.go
  function Test1 (line 11) | func Test1(request ziface.IRequest) {
  function Test2 (line 14) | func Test2(request ziface.IRequest) {
  function Test3 (line 17) | func Test3(request ziface.IRequest) {
  function Test4 (line 20) | func Test4(request ziface.IRequest) {
  function Test5 (line 23) | func Test5(request ziface.IRequest) {
  function Test6 (line 26) | func Test6(request ziface.IRequest) {
  type router (line 30) | type router struct
    method PreHandle (line 34) | func (r *router) PreHandle(req ziface.IRequest) {
    method Handle (line 37) | func (r *router) Handle(req ziface.IRequest) {
    method PostHandle (line 41) | func (r *router) PostHandle(req ziface.IRequest) {
  function main (line 45) | func main() {

FILE: examples/zinx_server/main.go
  function DoConnectionBegin (line 18) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 33) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 47) | func main() {

FILE: examples/zinx_server/s_router/hello.go
  type HelloZinxRouter (line 9) | type HelloZinxRouter struct
    method Handle (line 14) | func (this *HelloZinxRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_server/s_router/ping.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {

FILE: examples/zinx_tls/client/client.go
  type PongRouter (line 14) | type PongRouter struct
    method Handle (line 19) | func (this *PongRouter) Handle(request ziface.IRequest) {
  function wait (line 27) | func wait() {
  function main (line 34) | func main() {

FILE: examples/zinx_tls/server/server.go
  type PingRouter (line 21) | type PingRouter struct
    method Handle (line 26) | func (this *PingRouter) Handle(request ziface.IRequest) {
  function genExampleCrtAndKeyFile (line 42) | func genExampleCrtAndKeyFile(crtFileName, KeyFileName string) (err error) {
  function main (line 110) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.10Test/client0/Client0.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.10Test/client1/Client1.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.10Test/server/Server.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {
  type HelloZinxRouter (line 26) | type HelloZinxRouter struct
    method Handle (line 31) | func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
  function DoConnectionBegin (line 43) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 58) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 71) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.11Test/client0/Client0.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.11Test/client1/Client1.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.11Test/server/Server.go
  type PingRouter (line 16) | type PingRouter struct
    method Handle (line 21) | func (this *PingRouter) Handle(request ziface.IRequest) {
  type HelloZinxRouter (line 33) | type HelloZinxRouter struct
    method Handle (line 38) | func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
  function DoConnectionBegin (line 50) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 65) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 78) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.1Test/client/client.go
  function main (line 12) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.1Test/server/server.go
  function main (line 8) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.2Test/client/client.go
  function main (line 12) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.2Test/server/server.go
  function main (line 8) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.3Test/client/client.go
  function main (line 12) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.3Test/server/server.go
  type PingRouter (line 11) | type PingRouter struct
    method PreHandle (line 16) | func (this *PingRouter) PreHandle(request ziface.IRequest) {
    method Handle (line 25) | func (this *PingRouter) Handle(request ziface.IRequest) {
    method PostHandle (line 34) | func (this *PingRouter) PostHandle(request ziface.IRequest) {
  function main (line 42) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.4Test/client/client.go
  function main (line 12) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.4Test/server/server.go
  type PingRouter (line 11) | type PingRouter struct
    method PreHandle (line 16) | func (this *PingRouter) PreHandle(request ziface.IRequest) {
    method Handle (line 25) | func (this *PingRouter) Handle(request ziface.IRequest) {
    method PostHandle (line 34) | func (this *PingRouter) PostHandle(request ziface.IRequest) {
  function main (line 42) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.5Test/client/client.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.5Test/server/server.go
  type PingRouter (line 11) | type PingRouter struct
    method Handle (line 16) | func (this *PingRouter) Handle(request ziface.IRequest) {
  function main (line 34) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/client0/Client0.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/client1/Client1.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/server/Server.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {
  type HelloZinxRouter (line 26) | type HelloZinxRouter struct
    method Handle (line 31) | func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
  function main (line 42) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.8Test/client0/Client0.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.8Test/client1/Client1.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.8Test/server/Server.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {
  type HelloZinxRouter (line 26) | type HelloZinxRouter struct
    method Handle (line 31) | func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
  function main (line 42) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.9Test/client0/Client0.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.9Test/client1/Client1.go
  function main (line 14) | func main() {

FILE: examples/zinx_version_ex/ZinxV0.9Test/server/Server.go
  type PingRouter (line 10) | type PingRouter struct
    method Handle (line 15) | func (this *PingRouter) Handle(request ziface.IRequest) {
  type HelloZinxRouter (line 26) | type HelloZinxRouter struct
    method Handle (line 31) | func (this *HelloZinxRouter) Handle(request ziface.IRequest) {
  function DoConnectionBegin (line 43) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 52) | func DoConnectionLost(conn ziface.IConnection) {
  function main (line 56) | func main() {

FILE: examples/zinx_version_ex/datapackDemo/client/client.go
  function main (line 9) | func main() {

FILE: examples/zinx_version_ex/datapackDemo/server/server.go
  function main (line 11) | func main() {

FILE: examples/zinx_version_ex/protoDemo/main.go
  function main (line 10) | func main() {

FILE: examples/zinx_version_ex/protoDemo/pb/Person.pb.go
  constant _ (line 21) | _ = proto.ProtoPackageIsVersion3
  type PhoneType (line 24) | type PhoneType
    method String (line 44) | func (x PhoneType) String() string {
    method EnumDescriptor (line 48) | func (PhoneType) EnumDescriptor() ([]byte, []int) {
  constant PhoneType_MOBILE (line 27) | PhoneType_MOBILE PhoneType = 0
  constant PhoneType_HOME (line 28) | PhoneType_HOME   PhoneType = 1
  constant PhoneType_WORK (line 29) | PhoneType_WORK   PhoneType = 2
  type Person (line 53) | type Person struct
    method Reset (line 63) | func (m *Person) Reset()         { *m = Person{} }
    method String (line 64) | func (m *Person) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 65) | func (*Person) ProtoMessage()    {}
    method Descriptor (line 66) | func (*Person) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 70) | func (m *Person) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 73) | func (m *Person) XXX_Marshal(b []byte, deterministic bool) ([]byte, er...
    method XXX_Merge (line 76) | func (m *Person) XXX_Merge(src proto.Message) {
    method XXX_Size (line 79) | func (m *Person) XXX_Size() int {
    method XXX_DiscardUnknown (line 82) | func (m *Person) XXX_DiscardUnknown() {
    method GetName (line 88) | func (m *Person) GetName() string {
    method GetAge (line 95) | func (m *Person) GetAge() int32 {
    method GetEmails (line 102) | func (m *Person) GetEmails() []string {
    method GetPhones (line 109) | func (m *Person) GetPhones() []*PhoneNumber {
  type PhoneNumber (line 117) | type PhoneNumber struct
    method Reset (line 125) | func (m *PhoneNumber) Reset()         { *m = PhoneNumber{} }
    method String (line 126) | func (m *PhoneNumber) String() string { return proto.CompactTextString...
    method ProtoMessage (line 127) | func (*PhoneNumber) ProtoMessage()    {}
    method Descriptor (line 128) | func (*PhoneNumber) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 132) | func (m *PhoneNumber) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 135) | func (m *PhoneNumber) XXX_Marshal(b []byte, deterministic bool) ([]byt...
    method XXX_Merge (line 138) | func (m *PhoneNumber) XXX_Merge(src proto.Message) {
    method XXX_Size (line 141) | func (m *PhoneNumber) XXX_Size() int {
    method XXX_DiscardUnknown (line 144) | func (m *PhoneNumber) XXX_DiscardUnknown() {
    method GetNumber (line 150) | func (m *PhoneNumber) GetNumber() string {
    method GetType (line 157) | func (m *PhoneNumber) GetType() PhoneType {
  function init (line 164) | func init() {
  function init (line 170) | func init() { proto.RegisterFile("Person.proto", fileDescriptor_841ab639...

FILE: examples/zinx_websocket/client/client.go
  type PositionClientRouter (line 14) | type PositionClientRouter struct
    method Handle (line 18) | func (this *PositionClientRouter) Handle(request ziface.IRequest) {
  function business (line 23) | func business(conn ziface.IConnection) {
  function DoClientConnectedBegin (line 36) | func DoClientConnectedBegin(conn ziface.IConnection) {
  function wait (line 44) | func wait() {
  function main (line 51) | func main() {

FILE: examples/zinx_websocket/minicode/app.js
  method onLaunch (line 3) | onLaunch() {
  method encodeTLV (line 27) | encodeTLV(type, value) {
  method decodeTLV (line 38) | decodeTLV(buffer) {

FILE: examples/zinx_websocket/minicode/index/index.js
  method onLoad (line 7) | onLoad() {

FILE: examples/zinx_websocket/server/server.go
  function main (line 9) | func main() {

FILE: logo/zinxlogo.go
  function PrintLogo (line 22) | func PrintLogo() {

FILE: zasync_op/async_op.go
  function Process (line 48) | func Process(opId int, asyncOp func()) {
  function getCurWorker (line 61) | func getCurWorker(opId int) *AsyncWorker {

FILE: zasync_op/async_op_result.go
  type AsyncOpResult (line 16) | type AsyncOpResult struct
    method GetReturnedObj (line 32) | func (aor *AsyncOpResult) GetReturnedObj() interface{} {
    method SetReturnedObj (line 37) | func (aor *AsyncOpResult) SetReturnedObj(val interface{}) {
    method OnComplete (line 50) | func (aor *AsyncOpResult) OnComplete(val func()) {
    method doComplete (line 66) | func (aor *AsyncOpResult) doComplete() {
  function NewAsyncOpResult (line 85) | func NewAsyncOpResult(conn ziface.IConnection) *AsyncOpResult {

FILE: zasync_op/async_worker.go
  type AsyncWorker (line 11) | type AsyncWorker struct
    method process (line 15) | func (aw *AsyncWorker) process(asyncOp func()) {
    method loopExecTask (line 38) | func (aw *AsyncWorker) loopExecTask() {

FILE: zconf/env.go
  constant EnvConfigFilePathKey (line 17) | EnvConfigFilePathKey     = "ZINX_CONFIG_FILE_PATH"
  constant EnvDefaultConfigFilePath (line 18) | EnvDefaultConfigFilePath = "/conf/zinx.json"
  type zEnv (line 23) | type zEnv struct
  function init (line 27) | func init() {
  function GetConfigFilePath (line 44) | func GetConfigFilePath() string {

FILE: zconf/userconf.go
  function UserConfToGlobal (line 9) | func UserConfToGlobal(config *Config) {

FILE: zconf/zconf.go
  constant ServerModeTcp (line 20) | ServerModeTcp       = "tcp"
  constant ServerModeWebsocket (line 21) | ServerModeWebsocket = "websocket"
  constant ServerModeKcp (line 22) | ServerModeKcp       = "kcp"
  constant WorkerModeHash (line 26) | WorkerModeHash = "Hash"
  constant WorkerModeBind (line 27) | WorkerModeBind = "Bind"
  constant WorkerModeDynamicBind (line 35) | WorkerModeDynamicBind = "DynamicBind"
  type Config (line 44) | type Config struct
    method Reload (line 142) | func (g *Config) Reload() {
    method Show (line 169) | func (g *Config) Show() {
    method HeartbeatMaxDuration (line 183) | func (g *Config) HeartbeatMaxDuration() time.Duration {
    method InitLogConfig (line 187) | func (g *Config) InitLogConfig() {
  function PathExists (line 126) | func PathExists(path string) (bool, error) {
  function init (line 206) | func init() {

FILE: zdecoder/crc.go
  function GetCrC (line 61) | func GetCrC(buff []byte) []byte {
  function IsComplete (line 78) | func IsComplete(src []byte, dst []byte) bool {
  function CheckCRC (line 89) | func CheckCRC(src []byte, crc []byte) bool {

FILE: zdecoder/htlvcrcdecoder.go
  constant HEADER_SIZE (line 53) | HEADER_SIZE = 5
  type HtlvCrcDecoder (line 55) | type HtlvCrcDecoder struct
    method GetLengthField (line 68) | func (hcd *HtlvCrcDecoder) GetLengthField() *ziface.LengthField {
    method decode (line 92) | func (hcd *HtlvCrcDecoder) decode(data []byte) *HtlvCrcDecoder {
    method Intercept (line 118) | func (hcd *HtlvCrcDecoder) Intercept(chain ziface.IChain) ziface.IcResp {
  function NewHTLVCRCDecoder (line 64) | func NewHTLVCRCDecoder() ziface.IDecoder {

FILE: zdecoder/ltvdecoder_little.go
  constant LTV_HEADER_SIZE (line 59) | LTV_HEADER_SIZE = 8
  type LTV_Little_Decoder (line 61) | type LTV_Little_Decoder struct
    method GetLengthField (line 71) | func (ltv *LTV_Little_Decoder) GetLengthField() *ziface.LengthField {
    method decode (line 98) | func (ltv *LTV_Little_Decoder) decode(data []byte) *LTV_Little_Decoder {
    method Intercept (line 114) | func (ltv *LTV_Little_Decoder) Intercept(chain ziface.IChain) ziface.I...
  function NewLTV_Little_Decoder (line 67) | func NewLTV_Little_Decoder() ziface.IDecoder {

FILE: zdecoder/tlvdecoder.go
  constant TLV_HEADER_SIZE (line 60) | TLV_HEADER_SIZE = 8
  type TLVDecoder (line 62) | type TLVDecoder struct
    method GetLengthField (line 72) | func (tlv *TLVDecoder) GetLengthField() *ziface.LengthField {
    method decode (line 97) | func (tlv *TLVDecoder) decode(data []byte) *TLVDecoder {
    method Intercept (line 113) | func (tlv *TLVDecoder) Intercept(chain ziface.IChain) ziface.IcResp {
  function NewTLVDecoder (line 68) | func NewTLVDecoder() ziface.IDecoder {

FILE: ziface/iclient.go
  type IClient (line 13) | type IClient interface

FILE: ziface/iconnection.go
  type IConnection (line 14) | type IConnection interface

FILE: ziface/iconnmanager.go
  type IConnManager (line 7) | type IConnManager interface

FILE: ziface/idatapack.go
  type IDataPack (line 9) | type IDataPack interface
  constant ZinxDataPack (line 17) | ZinxDataPack    string = "zinx_pack_tlv_big_endian"
  constant ZinxDataPackOld (line 18) | ZinxDataPackOld string = "zinx_pack_ltv_little_endian"
  constant ZinxMessage (line 26) | ZinxMessage string = "zinx_message"

FILE: ziface/idecoder.go
  type IDecoder (line 3) | type IDecoder interface

FILE: ziface/iheartbeat.go
  type IHeartbeatChecker (line 3) | type IHeartbeatChecker interface
  type HeartBeatMsgFunc (line 21) | type HeartBeatMsgFunc
  type HeartBeatFunc (line 25) | type HeartBeatFunc
  type OnRemoteNotAlive (line 29) | type OnRemoteNotAlive
  type HeartBeatOption (line 31) | type HeartBeatOption struct
  constant HeartBeatDefaultMsgID (line 40) | HeartBeatDefaultMsgID uint32 = 99999

FILE: ziface/iinterceptor.go
  type IcReq (line 11) | type IcReq interface
  type IcResp (line 15) | type IcResp interface
  type IInterceptor (line 19) | type IInterceptor interface
  type IChain (line 27) | type IChain interface

FILE: ziface/ilengthfield.go
  type IFrameDecoder (line 5) | type IFrameDecoder interface
  type LengthField (line 11) | type LengthField struct

FILE: ziface/ilogger.go
  type ILogger (line 5) | type ILogger interface

FILE: ziface/imessage.go
  type IMessage (line 7) | type IMessage interface

FILE: ziface/imsghandler.go
  type IMsgHandle (line 7) | type IMsgHandle interface

FILE: ziface/inotify.go
  type Inotify (line 3) | type Inotify interface

FILE: ziface/irequest.go
  type HandleStep (line 6) | type HandleStep
  type IFuncRequest (line 9) | type IFuncRequest interface
  type IRequest (line 16) | type IRequest interface
  type BaseRequest (line 60) | type BaseRequest struct
    method GetConnection (line 62) | func (br *BaseRequest) GetConnection() IConnection       { return nil }
    method GetData (line 63) | func (br *BaseRequest) GetData() []byte                  { return nil }
    method GetMsgID (line 64) | func (br *BaseRequest) GetMsgID() uint32                 { return 0 }
    method GetMessage (line 65) | func (br *BaseRequest) GetMessage() IMessage             { return nil }
    method GetResponse (line 66) | func (br *BaseRequest) GetResponse() IcResp              { return nil }
    method SetResponse (line 67) | func (br *BaseRequest) SetResponse(resp IcResp)          {}
    method BindRouter (line 68) | func (br *BaseRequest) BindRouter(router IRouter)        {}
    method Call (line 69) | func (br *BaseRequest) Call()                            {}
    method Abort (line 70) | func (br *BaseRequest) Abort()                           {}
    method Goto (line 71) | func (br *BaseRequest) Goto(HandleStep)                  {}
    method BindRouterSlices (line 72) | func (br *BaseRequest) BindRouterSlices([]RouterHandler) {}
    method RouterSlicesNext (line 73) | func (br *BaseRequest) RouterSlicesNext()                {}
    method Copy (line 74) | func (br *BaseRequest) Copy() IRequest                   { return nil }
    method Set (line 76) | func (br *BaseRequest) Set(key string, value interface{}) {}
    method Get (line 78) | func (br *BaseRequest) Get(key string) (value interface{}, exists bool...

FILE: ziface/irouter.go
  type IRouter (line 12) | type IRouter interface
  type RouterHandler (line 23) | type RouterHandler
  type IRouterSlices (line 24) | type IRouterSlices interface
  type IGroupRouterSlices (line 38) | type IGroupRouterSlices interface

FILE: ziface/iserver.go
  type IServer (line 12) | type IServer interface

FILE: ziface/options.go
  type MsgSendOptionObj (line 5) | type MsgSendOptionObj struct
  type MsgSendOption (line 9) | type MsgSendOption
  function WithSendMsgTimeout (line 11) | func WithSendMsgTimeout(timeout time.Duration) MsgSendOption {

FILE: zinterceptor/chain.go
  type Chain (line 10) | type Chain struct
    method Request (line 24) | func (c *Chain) Request() ziface.IcReq {
    method Proceed (line 28) | func (c *Chain) Proceed(request ziface.IcReq) ziface.IcResp {
    method GetIMessage (line 39) | func (c *Chain) GetIMessage() ziface.IMessage {
    method ProceedWithIMessage (line 56) | func (c *Chain) ProceedWithIMessage(iMessage ziface.IMessage, response...
    method ShouldIRequest (line 79) | func (c *Chain) ShouldIRequest(icReq ziface.IcReq) ziface.IRequest {
  function NewChain (line 16) | func NewChain(list []ziface.IInterceptor, pos int, req ziface.IcReq) zif...

FILE: zinterceptor/framedecoder.go
  type FrameDecoder (line 307) | type FrameDecoder struct
    method fail (line 351) | func (d *FrameDecoder) fail(frameLength int64) {
    method discardingTooLongFrameFunc (line 362) | func (d *FrameDecoder) discardingTooLongFrameFunc(buffer *bytes.Buffer) {
    method getUnadjustedFrameLength (line 383) | func (d *FrameDecoder) getUnadjustedFrameLength(buf *bytes.Buffer, off...
    method failOnNegativeLengthField (line 427) | func (d *FrameDecoder) failOnNegativeLengthField(in *bytes.Buffer, fra...
    method failIfNecessary (line 432) | func (d *FrameDecoder) failIfNecessary(firstDetectionOfTooLongFrame bo...
    method exceededFrameLength (line 459) | func (d *FrameDecoder) exceededFrameLength(in *bytes.Buffer, frameLeng...
    method failOnFrameLengthLessThanInitialBytesToStrip (line 489) | func (d *FrameDecoder) failOnFrameLengthLessThanInitialBytesToStrip(in...
    method decode (line 494) | func (d *FrameDecoder) decode(buf []byte) []byte {
    method Decode (line 578) | func (d *FrameDecoder) Decode(buff []byte) [][]byte {
  function NewFrameDecoder (line 318) | func NewFrameDecoder(lf ziface.LengthField) ziface.IFrameDecoder {
  function NewFrameDecoderByParams (line 340) | func NewFrameDecoderByParams(maxFrameLength uint64, lengthFieldOffset, l...

FILE: zinx_app_demo/mmo_game/api/move.go
  type MoveApi (line 15) | type MoveApi struct
    method Handle (line 19) | func (*MoveApi) Handle(request ziface.IRequest) {

FILE: zinx_app_demo/mmo_game/api/world_chat.go
  type WorldChatApi (line 15) | type WorldChatApi struct
    method Handle (line 19) | func (*WorldChatApi) Handle(request ziface.IRequest) {

FILE: zinx_app_demo/mmo_game/client_AI_robot.go
  type Message (line 21) | type Message struct
  type TcpClient (line 27) | type TcpClient struct
    method Unpack (line 37) | func (this *TcpClient) Unpack(headdata []byte) (head *Message, err err...
    method Pack (line 60) | func (this *TcpClient) Pack(msgID uint32, dataBytes []byte) (out []byt...
    method SendMsg (line 81) | func (this *TcpClient) SendMsg(msgID uint32, data proto.Message) {
    method AIRobotAction (line 100) | func (this *TcpClient) AIRobotAction() {
    method DoMsg (line 163) | func (this *TcpClient) DoMsg(msg *Message) {
    method Start (line 201) | func (this *TcpClient) Start() {
  function NewTcpClient (line 247) | func NewTcpClient(ip string, port int) *TcpClient {
  function main (line 270) | func main() {

FILE: zinx_app_demo/mmo_game/core/aoi.go
  constant AOI_MIN_X (line 6) | AOI_MIN_X  int = 85
  constant AOI_MAX_X (line 7) | AOI_MAX_X  int = 410
  constant AOI_CNTS_X (line 8) | AOI_CNTS_X int = 10
  constant AOI_MIN_Y (line 9) | AOI_MIN_Y  int = 75
  constant AOI_MAX_Y (line 10) | AOI_MAX_Y  int = 400
  constant AOI_CNTS_Y (line 11) | AOI_CNTS_Y int = 20
  type AOIManager (line 15) | type AOIManager struct
    method grIDWIDth (line 62) | func (m *AOIManager) grIDWIDth() int {
    method grIDLength (line 68) | func (m *AOIManager) grIDLength() int {
    method String (line 74) | func (m *AOIManager) String() string {
    method GetSurroundGrIDsByGID (line 86) | func (m *AOIManager) GetSurroundGrIDsByGID(gID int) (grIDs []*GrID) {
    method GetGIDByPos (line 136) | func (m *AOIManager) GetGIDByPos(x, y float32) int {
    method GetPIDsByPos (line 145) | func (m *AOIManager) GetPIDsByPos(x, y float32) (playerIDs []int) {
    method GetPIDsByGID (line 163) | func (m *AOIManager) GetPIDsByGID(gID int) (playerIDs []int) {
    method RemovePIDFromGrID (line 170) | func (m *AOIManager) RemovePIDFromGrID(pID, gID int) {
    method AddPIDToGrID (line 176) | func (m *AOIManager) AddPIDToGrID(pID, gID int) {
    method AddToGrIDByPos (line 182) | func (m *AOIManager) AddToGrIDByPos(pID int, x, y float32) {
    method RemoveFromGrIDByPos (line 190) | func (m *AOIManager) RemoveFromGrIDByPos(pID int, x, y float32) {
  function NewAOIManager (line 26) | func NewAOIManager(minX, maxX, cntsX, minY, maxY, cntsY int) *AOIManager {

FILE: zinx_app_demo/mmo_game/core/aoi_test.go
  function TestNewAOIManager (line 8) | func TestNewAOIManager(t *testing.T) {
  function TestAOIManagerSuroundGrIDsByGID (line 13) | func TestAOIManagerSuroundGrIDsByGID(t *testing.T) {

FILE: zinx_app_demo/mmo_game/core/grid.go
  type GrID (line 9) | type GrID struct
    method Add (line 32) | func (g *GrID) Add(playerID int) {
    method Remove (line 40) | func (g *GrID) Remove(playerID int) {
    method GetPlyerIDs (line 48) | func (g *GrID) GetPlyerIDs() (playerIDs []int) {
    method String (line 60) | func (g *GrID) String() string {
  function NewGrID (line 20) | func NewGrID(gID, minX, maxX, minY, maxY int) *GrID {

FILE: zinx_app_demo/mmo_game/core/player.go
  type Player (line 15) | type Player struct
    method SyncPID (line 49) | func (p *Player) SyncPID() {
    method BroadCastStartPosition (line 63) | func (p *Player) BroadCastStartPosition() {
    method SyncSurrounding (line 87) | func (p *Player) SyncSurrounding() {
    method Talk (line 154) | func (p *Player) Talk(content string) {
    method UpdatePos (line 177) | func (p *Player) UpdatePos(x float32, y float32, z float32, v float32) {
    method OnExchangeAoiGrID (line 235) | func (p *Player) OnExchangeAoiGrID(oldGID, newGID int) error {
    method GetSurroundingPlayers (line 351) | func (p *Player) GetSurroundingPlayers() []*Player {
    method LostConnection (line 368) | func (p *Player) LostConnection() {
    method SendMsg (line 394) | func (p *Player) SendMsg(msgID uint32, data proto.Message) {
  function NewPlayer (line 29) | func NewPlayer(conn ziface.IConnection) *Player {

FILE: zinx_app_demo/mmo_game/core/world_manager.go
  type WorldManager (line 8) | type WorldManager struct
    method AddPlayer (line 29) | func (wm *WorldManager) AddPlayer(player *Player) {
    method RemovePlayerByPID (line 43) | func (wm *WorldManager) RemovePlayerByPID(pID int32) {
    method GetPlayerByPID (line 51) | func (wm *WorldManager) GetPlayerByPID(pID int32) *Player {
    method GetAllPlayers (line 60) | func (wm *WorldManager) GetAllPlayers() []*Player {
    method GetPlayersByGID (line 79) | func (wm *WorldManager) GetPlayersByGID(gID int) []*Player {
  function init (line 20) | func init() {

FILE: zinx_app_demo/mmo_game/pb/msg.pb.go
  constant _ (line 21) | _ = proto.ProtoPackageIsVersion3
  type SyncPID (line 25) | type SyncPID struct
    method Reset (line 32) | func (m *SyncPID) Reset()         { *m = SyncPID{} }
    method String (line 33) | func (m *SyncPID) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 34) | func (*SyncPID) ProtoMessage()    {}
    method Descriptor (line 35) | func (*SyncPID) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 39) | func (m *SyncPID) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 42) | func (m *SyncPID) XXX_Marshal(b []byte, deterministic bool) ([]byte, e...
    method XXX_Merge (line 45) | func (m *SyncPID) XXX_Merge(src proto.Message) {
    method XXX_Size (line 48) | func (m *SyncPID) XXX_Size() int {
    method XXX_DiscardUnknown (line 51) | func (m *SyncPID) XXX_DiscardUnknown() {
    method GetPID (line 57) | func (m *SyncPID) GetPID() int32 {
  type Position (line 65) | type Position struct
    method Reset (line 75) | func (m *Position) Reset()         { *m = Position{} }
    method String (line 76) | func (m *Position) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 77) | func (*Position) ProtoMessage()    {}
    method Descriptor (line 78) | func (*Position) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 82) | func (m *Position) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 85) | func (m *Position) XXX_Marshal(b []byte, deterministic bool) ([]byte, ...
    method XXX_Merge (line 88) | func (m *Position) XXX_Merge(src proto.Message) {
    method XXX_Size (line 91) | func (m *Position) XXX_Size() int {
    method XXX_DiscardUnknown (line 94) | func (m *Position) XXX_DiscardUnknown() {
    method GetX (line 100) | func (m *Position) GetX() float32 {
    method GetY (line 107) | func (m *Position) GetY() float32 {
    method GetZ (line 114) | func (m *Position) GetZ() float32 {
    method GetV (line 121) | func (m *Position) GetV() float32 {
  type BroadCast (line 130) | type BroadCast struct
    method Reset (line 145) | func (m *BroadCast) Reset()         { *m = BroadCast{} }
    method String (line 146) | func (m *BroadCast) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 147) | func (*BroadCast) ProtoMessage()    {}
    method Descriptor (line 148) | func (*BroadCast) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 152) | func (m *BroadCast) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 155) | func (m *BroadCast) XXX_Marshal(b []byte, deterministic bool) ([]byte,...
    method XXX_Merge (line 158) | func (m *BroadCast) XXX_Merge(src proto.Message) {
    method XXX_Size (line 161) | func (m *BroadCast) XXX_Size() int {
    method XXX_DiscardUnknown (line 164) | func (m *BroadCast) XXX_DiscardUnknown() {
    method GetPID (line 170) | func (m *BroadCast) GetPID() int32 {
    method GetTp (line 177) | func (m *BroadCast) GetTp() int32 {
    method GetData (line 206) | func (m *BroadCast) GetData() isBroadCast_Data {
    method GetContent (line 213) | func (m *BroadCast) GetContent() string {
    method GetP (line 220) | func (m *BroadCast) GetP() *Position {
    method GetActionData (line 227) | func (m *BroadCast) GetActionData() int32 {
    method XXX_OneofWrappers (line 235) | func (*BroadCast) XXX_OneofWrappers() []interface{} {
  type isBroadCast_Data (line 184) | type isBroadCast_Data interface
  type BroadCast_Content (line 188) | type BroadCast_Content struct
    method isBroadCast_Data (line 200) | func (*BroadCast_Content) isBroadCast_Data() {}
  type BroadCast_P (line 192) | type BroadCast_P struct
    method isBroadCast_Data (line 202) | func (*BroadCast_P) isBroadCast_Data() {}
  type BroadCast_ActionData (line 196) | type BroadCast_ActionData struct
    method isBroadCast_Data (line 204) | func (*BroadCast_ActionData) isBroadCast_Data() {}
  type Talk (line 245) | type Talk struct
    method Reset (line 252) | func (m *Talk) Reset()         { *m = Talk{} }
    method String (line 253) | func (m *Talk) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 254) | func (*Talk) ProtoMessage()    {}
    method Descriptor (line 255) | func (*Talk) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 259) | func (m *Talk) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 262) | func (m *Talk) XXX_Marshal(b []byte, deterministic bool) ([]byte, erro...
    method XXX_Merge (line 265) | func (m *Talk) XXX_Merge(src proto.Message) {
    method XXX_Size (line 268) | func (m *Talk) XXX_Size() int {
    method XXX_DiscardUnknown (line 271) | func (m *Talk) XXX_DiscardUnknown() {
    method GetContent (line 277) | func (m *Talk) GetContent() string {
  type Player (line 285) | type Player struct
    method Reset (line 293) | func (m *Player) Reset()         { *m = Player{} }
    method String (line 294) | func (m *Player) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 295) | func (*Player) ProtoMessage()    {}
    method Descriptor (line 296) | func (*Player) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 300) | func (m *Player) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 303) | func (m *Player) XXX_Marshal(b []byte, deterministic bool) ([]byte, er...
    method XXX_Merge (line 306) | func (m *Player) XXX_Merge(src proto.Message) {
    method XXX_Size (line 309) | func (m *Player) XXX_Size() int {
    method XXX_DiscardUnknown (line 312) | func (m *Player) XXX_DiscardUnknown() {
    method GetPID (line 318) | func (m *Player) GetPID() int32 {
    method GetP (line 325) | func (m *Player) GetP() *Position {
  type SyncPlayers (line 334) | type SyncPlayers struct
    method Reset (line 341) | func (m *SyncPlayers) Reset()         { *m = SyncPlayers{} }
    method String (line 342) | func (m *SyncPlayers) String() string { return proto.CompactTextString...
    method ProtoMessage (line 343) | func (*SyncPlayers) ProtoMessage()    {}
    method Descriptor (line 344) | func (*SyncPlayers) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 348) | func (m *SyncPlayers) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 351) | func (m *SyncPlayers) XXX_Marshal(b []byte, deterministic bool) ([]byt...
    method XXX_Merge (line 354) | func (m *SyncPlayers) XXX_Merge(src proto.Message) {
    method XXX_Size (line 357) | func (m *SyncPlayers) XXX_Size() int {
    method XXX_DiscardUnknown (line 360) | func (m *SyncPlayers) XXX_DiscardUnknown() {
    method GetPs (line 366) | func (m *SyncPlayers) GetPs() []*Player {
  function init (line 373) | func init() {
  function init (line 382) | func init() { proto.RegisterFile("msg.proto", fileDescriptor_c06e4cca6c2...

FILE: zinx_app_demo/mmo_game/server.go
  function OnConnectionAdd (line 16) | func OnConnectionAdd(conn ziface.IConnection) {
  function OnConnectionLost (line 47) | func OnConnectionLost(conn ziface.IConnection) {
  function main (line 70) | func main() {

FILE: zlog/default.go
  type zinxDefaultLog (line 12) | type zinxDefaultLog struct
    method InfoF (line 14) | func (log *zinxDefaultLog) InfoF(format string, v ...interface{}) {
    method ErrorF (line 18) | func (log *zinxDefaultLog) ErrorF(format string, v ...interface{}) {
    method DebugF (line 22) | func (log *zinxDefaultLog) DebugF(format string, v ...interface{}) {
    method InfoFX (line 26) | func (log *zinxDefaultLog) InfoFX(ctx context.Context, format string, ...
    method ErrorFX (line 31) | func (log *zinxDefaultLog) ErrorFX(ctx context.Context, format string,...
    method DebugFX (line 36) | func (log *zinxDefaultLog) DebugFX(ctx context.Context, format string,...
  function SetLogger (line 41) | func SetLogger(newlog ziface.ILogger) {
  function Ins (line 45) | func Ins() ziface.ILogger {

FILE: zlog/logger_core.go
  constant LOG_MAX_BUF (line 31) | LOG_MAX_BUF = 1024 * 1024
  constant BitDate (line 37) | BitDate         = 1 << iota
  constant BitTime (line 38) | BitTime
  constant BitMicroSeconds (line 39) | BitMicroSeconds
  constant BitLongFile (line 40) | BitLongFile
  constant BitShortFile (line 41) | BitShortFile
  constant BitLevel (line 42) | BitLevel
  constant BitStdFlag (line 43) | BitStdFlag      = BitDate | BitTime
  constant BitDefault (line 44) | BitDefault      = BitLevel | BitShortFile | BitStdFlag
  constant LogDebug (line 49) | LogDebug = iota
  constant LogInfo (line 50) | LogInfo
  constant LogWarn (line 51) | LogWarn
  constant LogError (line 52) | LogError
  constant LogPanic (line 53) | LogPanic
  constant LogFatal (line 54) | LogFatal
  type ZinxLoggerCore (line 67) | type ZinxLoggerCore struct
    method SetLogHook (line 119) | func (log *ZinxLoggerCore) SetLogHook(f func([]byte)) {
    method formatHeader (line 131) | func (log *ZinxLoggerCore) formatHeader(t time.Time, file string, line...
    method OutPut (line 197) | func (log *ZinxLoggerCore) OutPut(level int, s string) error {
    method verifyLogIsolation (line 242) | func (log *ZinxLoggerCore) verifyLogIsolation(logLevel int) bool {
    method Debugf (line 246) | func (log *ZinxLoggerCore) Debugf(format string, v ...interface{}) {
    method Debug (line 253) | func (log *ZinxLoggerCore) Debug(v ...interface{}) {
    method Infof (line 260) | func (log *ZinxLoggerCore) Infof(format string, v ...interface{}) {
    method Info (line 267) | func (log *ZinxLoggerCore) Info(v ...interface{}) {
    method Warnf (line 274) | func (log *ZinxLoggerCore) Warnf(format string, v ...interface{}) {
    method Warn (line 281) | func (log *ZinxLoggerCore) Warn(v ...interface{}) {
    method Errorf (line 288) | func (log *ZinxLoggerCore) Errorf(format string, v ...interface{}) {
    method Error (line 295) | func (log *ZinxLoggerCore) Error(v ...interface{}) {
    method Fatalf (line 302) | func (log *ZinxLoggerCore) Fatalf(format string, v ...interface{}) {
    method Fatal (line 310) | func (log *ZinxLoggerCore) Fatal(v ...interface{}) {
    method Panicf (line 318) | func (log *ZinxLoggerCore) Panicf(format string, v ...interface{}) {
    method Panic (line 327) | func (log *ZinxLoggerCore) Panic(v ...interface{}) {
    method Stack (line 336) | func (log *ZinxLoggerCore) Stack(v ...interface{}) {
    method Flags (line 348) | func (log *ZinxLoggerCore) Flags() int {
    method ResetFlags (line 356) | func (log *ZinxLoggerCore) ResetFlags(flag int) {
    method AddFlag (line 364) | func (log *ZinxLoggerCore) AddFlag(flag int) {
    method SetPrefix (line 372) | func (log *ZinxLoggerCore) SetPrefix(prefix string) {
    method SetLogFile (line 380) | func (log *ZinxLoggerCore) SetLogFile(fileDir string, fileName string) {
    method SetMaxAge (line 388) | func (log *ZinxLoggerCore) SetMaxAge(ma int) {
    method SetMaxSize (line 398) | func (log *ZinxLoggerCore) SetMaxSize(ms int64) {
    method SetCons (line 408) | func (log *ZinxLoggerCore) SetCons(b bool) {
    method closeFile (line 419) | func (log *ZinxLoggerCore) closeFile() {
    method SetLogLevel (line 425) | func (log *ZinxLoggerCore) SetLogLevel(logLevel int) {
  function NewZinxLog (line 102) | func NewZinxLog(prefix string, flag int) *ZinxLoggerCore {
  function CleanZinxLog (line 115) | func CleanZinxLog(log *ZinxLoggerCore) {
  function itoa (line 433) | func itoa(buf *bytes.Buffer, i int, wID int) {

FILE: zlog/stdzlog.go
  function Flags (line 28) | func Flags() int {
  function ResetFlags (line 33) | func ResetFlags(flag int) {
  function AddFlag (line 38) | func AddFlag(flag int) {
  function SetPrefix (line 43) | func SetPrefix(prefix string) {
  function SetLogFile (line 48) | func SetLogFile(fileDir string, fileName string) {
  function SetMaxAge (line 53) | func SetMaxAge(ma int) {
  function SetMaxSize (line 58) | func SetMaxSize(ms int64) {
  function SetCons (line 63) | func SetCons(b bool) {
  function SetLogLevel (line 68) | func SetLogLevel(logLevel int) {
  function Debugf (line 72) | func Debugf(format string, v ...interface{}) {
  function Debug (line 76) | func Debug(v ...interface{}) {
  function Infof (line 80) | func Infof(format string, v ...interface{}) {
  function Info (line 84) | func Info(v ...interface{}) {
  function Warnf (line 88) | func Warnf(format string, v ...interface{}) {
  function Warn (line 92) | func Warn(v ...interface{}) {
  function Errorf (line 96) | func Errorf(format string, v ...interface{}) {
  function Error (line 100) | func Error(v ...interface{}) {
  function Fatalf (line 104) | func Fatalf(format string, v ...interface{}) {
  function Fatal (line 108) | func Fatal(v ...interface{}) {
  function Panicf (line 112) | func Panicf(format string, v ...interface{}) {
  function Panic (line 116) | func Panic(v ...interface{}) {
  function Stack (line 120) | func Stack(v ...interface{}) {
  function init (line 124) | func init() {

FILE: zlog/zlog_test.go
  function TestStdZLog (line 9) | func TestStdZLog(t *testing.T) {
  function TestZLogger (line 63) | func TestZLogger(t *testing.T) {

FILE: znet/acceptdelay.go
  constant maxDelay (line 8) | maxDelay = 1 * time.Second
  function init (line 13) | func init() {
  type acceptDelay (line 17) | type acceptDelay struct
    method Delay (line 21) | func (d *acceptDelay) Delay() {
    method Reset (line 26) | func (d *acceptDelay) Reset() {
    method Up (line 30) | func (d *acceptDelay) Up() {
    method do (line 41) | func (d *acceptDelay) do() {

FILE: znet/acceptdelay_test.go
  function setup (line 12) | func setup() {
  function teardown (line 16) | func teardown() {
  function TestDelay (line 21) | func TestDelay(t *testing.T) {
  function TestMain (line 34) | func TestMain(m *testing.M) {

FILE: znet/callbacks.go
  type callbackNode (line 5) | type callbackNode struct
  type callbacks (line 14) | type callbacks struct
    method Add (line 26) | func (t *callbacks) Add(handler, key any, callback func()) {
    method Remove (line 61) | func (t *callbacks) Remove(handler, key any) {
    method Invoke (line 91) | func (t *callbacks) Invoke() {
    method Len (line 100) | func (t *callbacks) Len() int {

FILE: znet/callbacks_test.go
  function TestCallback (line 7) | func TestCallback(t *testing.T) {
  function TestCallbackInvokePanicPropagation (line 103) | func TestCallbackInvokePanicPropagation(t *testing.T) {

FILE: znet/chainbuilder.go
  type chainBuilder (line 16) | type chainBuilder struct
    method Head (line 29) | func (ic *chainBuilder) Head(interceptor ziface.IInterceptor) {
    method Tail (line 34) | func (ic *chainBuilder) Tail(interceptor ziface.IInterceptor) {
    method AddInterceptor (line 39) | func (ic *chainBuilder) AddInterceptor(interceptor ziface.IInterceptor) {
    method Execute (line 44) | func (ic *chainBuilder) Execute(req ziface.IcReq) ziface.IcResp {
  function newChainBuilder (line 22) | func newChainBuilder() *chainBuilder {

FILE: znet/client.go
  type Client (line 20) | type Client struct
    method notifyErr (line 123) | func (c *Client) notifyErr(err error) {
    method Restart (line 132) | func (c *Client) Restart() {
    method Start (line 228) | func (c *Client) Start() {
    method StartHeartBeat (line 241) | func (c *Client) StartHeartBeat(interval time.Duration) {
    method StartHeartBeatWithOption (line 257) | func (c *Client) StartHeartBeatWithOption(interval time.Duration, opti...
    method Stop (line 276) | func (c *Client) Stop() {
    method AddRouter (line 299) | func (c *Client) AddRouter(msgID uint32, router ziface.IRouter) {
    method Conn (line 303) | func (c *Client) Conn() ziface.IConnection {
    method setConn (line 309) | func (c *Client) setConn(con ziface.IConnection) {
    method SetOnConnStart (line 315) | func (c *Client) SetOnConnStart(hookFunc func(ziface.IConnection)) {
    method SetOnConnStop (line 319) | func (c *Client) SetOnConnStop(hookFunc func(ziface.IConnection)) {
    method GetOnConnStart (line 323) | func (c *Client) GetOnConnStart() func(ziface.IConnection) {
    method GetOnConnStop (line 327) | func (c *Client) GetOnConnStop() func(ziface.IConnection) {
    method GetPacket (line 331) | func (c *Client) GetPacket() ziface.IDataPack {
    method SetPacket (line 335) | func (c *Client) SetPacket(packet ziface.IDataPack) {
    method GetMsgHandler (line 339) | func (c *Client) GetMsgHandler() ziface.IMsgHandle {
    method AddInterceptor (line 343) | func (c *Client) AddInterceptor(interceptor ziface.IInterceptor) {
    method SetDecoder (line 347) | func (c *Client) SetDecoder(decoder ziface.IDecoder) {
    method GetLengthField (line 350) | func (c *Client) GetLengthField() *ziface.LengthField {
    method GetErrChan (line 357) | func (c *Client) GetErrChan() <-chan error {
    method SetName (line 361) | func (c *Client) SetName(name string) {
    method GetName (line 365) | func (c *Client) GetName() string {
    method SetUrl (line 369) | func (c *Client) SetUrl(url *url.URL) {
    method GetUrl (line 373) | func (c *Client) GetUrl() *url.URL {
    method SetWsHeader (line 377) | func (c *Client) SetWsHeader(header http.Header) {
    method GetWsHeader (line 381) | func (c *Client) GetWsHeader() http.Header {
  function NewClient (line 64) | func NewClient(ip string, port int, opts ...ClientOption) ziface.IClient {
  function NewWsClient (line 88) | func NewWsClient(ip string, port int, opts ...ClientOption) ziface.IClie...
  function NewTLSClient (line 113) | func NewTLSClient(ip string, port int, opts ...ClientOption) ziface.ICli...

FILE: znet/connection.go
  type CallBackFunc (line 25) | type CallBackFunc
  type Connection (line 30) | type Connection struct
    method StartWriter (line 197) | func (c *Connection) StartWriter() {
    method StartReader (line 231) | func (c *Connection) StartReader() {
    method Start (line 296) | func (c *Connection) Start() {
    method Stop (line 333) | func (c *Connection) Stop() {
    method GetConnection (line 337) | func (c *Connection) GetConnection() net.Conn {
    method GetWsConn (line 341) | func (c *Connection) GetWsConn() *websocket.Conn {
    method GetTCPConnection (line 346) | func (c *Connection) GetTCPConnection() net.Conn {
    method GetConnID (line 350) | func (c *Connection) GetConnID() uint64 {
    method GetConnIdStr (line 354) | func (c *Connection) GetConnIdStr() string {
    method GetWorkerID (line 358) | func (c *Connection) GetWorkerID() uint32 {
    method RemoteAddr (line 362) | func (c *Connection) RemoteAddr() net.Addr {
    method LocalAddr (line 366) | func (c *Connection) LocalAddr() net.Addr {
    method Flush (line 370) | func (c *Connection) Flush() error {
    method Send (line 377) | func (c *Connection) Send(data []byte) error {
    method SendBuf (line 389) | func (c *Connection) SendBuf(data []byte) error {
    method SendToQueue (line 401) | func (c *Connection) SendToQueue(data []byte, opts ...ziface.MsgSendOp...
    method SendMsg (line 447) | func (c *Connection) SendMsg(msgID uint32, data []byte) error {
    method SendBuffMsg (line 468) | func (c *Connection) SendBuffMsg(msgID uint32, data []byte, opts ...zi...
    method SetProperty (line 478) | func (c *Connection) SetProperty(key string, value interface{}) {
    method GetProperty (line 488) | func (c *Connection) GetProperty(key string) (interface{}, error) {
    method RemoveProperty (line 499) | func (c *Connection) RemoveProperty(key string) {
    method Context (line 506) | func (c *Connection) Context() context.Context {
    method finalizer (line 510) | func (c *Connection) finalizer() {
    method callOnConnStart (line 541) | func (c *Connection) callOnConnStart() {
    method callOnConnStop (line 548) | func (c *Connection) callOnConnStop() {
    method IsAlive (line 555) | func (c *Connection) IsAlive() bool {
    method updateActivity (line 565) | func (c *Connection) updateActivity() {
    method SetHeartBeat (line 569) | func (c *Connection) SetHeartBeat(checker ziface.IHeartbeatChecker) {
    method LocalAddrString (line 573) | func (c *Connection) LocalAddrString() string {
    method RemoteAddrString (line 577) | func (c *Connection) RemoteAddrString() string {
    method GetName (line 581) | func (c *Connection) GetName() string {
    method GetMsgHandler (line 585) | func (c *Connection) GetMsgHandler() ziface.IMsgHandle {
    method isClosed (line 589) | func (c *Connection) isClosed() bool {
    method setStartWriterFlag (line 593) | func (c *Connection) setStartWriterFlag() bool {
    method AddCloseCallback (line 597) | func (s *Connection) AddCloseCallback(handler, key interface{}, f func...
    method RemoveCloseCallback (line 606) | func (s *Connection) RemoveCloseCallback(handler, key interface{}) {
    method InvokeCloseCallbacks (line 615) | func (s *Connection) InvokeCloseCallbacks() {
  function newServerConn (line 127) | func newServerConn(server ziface.IServer, conn net.Conn, connID uint64) ...
  function newClientConn (line 167) | func newClientConn(client ziface.IClient, conn net.Conn) ziface.IConnect...

FILE: znet/connmanager.go
  type ConnManager (line 12) | type ConnManager struct
    method Add (line 22) | func (connMgr *ConnManager) Add(conn ziface.IConnection) {
    method Remove (line 29) | func (connMgr *ConnManager) Remove(conn ziface.IConnection) {
    method Get (line 36) | func (connMgr *ConnManager) Get(connID uint64) (ziface.IConnection, er...
    method Get2 (line 47) | func (connMgr *ConnManager) Get2(strConnId string) (ziface.IConnection...
    method Len (line 56) | func (connMgr *ConnManager) Len() int {
    method ClearConn (line 63) | func (connMgr *ConnManager) ClearConn() {
    method GetAllConnID (line 78) | func (connMgr *ConnManager) GetAllConnID() []uint64 {
    method GetAllConnIdStr (line 95) | func (connMgr *ConnManager) GetAllConnIdStr() []string {
    method Range (line 99) | func (connMgr *ConnManager) Range(cb func(uint64, ziface.IConnection, ...
    method Range2 (line 114) | func (connMgr *ConnManager) Range2(cb func(string, ziface.IConnection,...
  function newConnManager (line 16) | func newConnManager() *ConnManager {

FILE: znet/defaultrouterfunc.go
  constant StackBegin (line 18) | StackBegin = 3
  constant StackEnd (line 21) | StackEnd = 5
  function RouterRecovery (line 32) | func RouterRecovery(request ziface.IRequest) {
  function RouterTime (line 51) | func RouterTime(request ziface.IRequest) {
  function getInfo (line 58) | func getInfo(ship int) (infoStr string) {

FILE: znet/heartbeat.go
  type HeartbeatChecker (line 11) | type HeartbeatChecker struct
    method SetOnRemoteNotAlive (line 73) | func (h *HeartbeatChecker) SetOnRemoteNotAlive(f ziface.OnRemoteNotAli...
    method SetHeartbeatMsgFunc (line 79) | func (h *HeartbeatChecker) SetHeartbeatMsgFunc(f ziface.HeartBeatMsgFu...
    method SetHeartbeatFunc (line 85) | func (h *HeartbeatChecker) SetHeartbeatFunc(beatFunc ziface.HeartBeatF...
    method BindRouter (line 91) | func (h *HeartbeatChecker) BindRouter(msgID uint32, router ziface.IRou...
    method BindRouterSlices (line 98) | func (h *HeartbeatChecker) BindRouterSlices(msgID uint32, handlers ......
    method start (line 105) | func (h *HeartbeatChecker) start() {
    method Start (line 118) | func (h *HeartbeatChecker) Start() {
    method Stop (line 122) | func (h *HeartbeatChecker) Stop() {
    method SendHeartBeatMsg (line 127) | func (h *HeartbeatChecker) SendHeartBeatMsg() error {
    method check (line 140) | func (h *HeartbeatChecker) check() (err error) {
    method BindConn (line 159) | func (h *HeartbeatChecker) BindConn(conn ziface.IConnection) {
    method Clone (line 166) | func (h *HeartbeatChecker) Clone() ziface.IHeartbeatChecker {
    method MsgID (line 185) | func (h *HeartbeatChecker) MsgID() uint32 {
    method Router (line 189) | func (h *HeartbeatChecker) Router() ziface.IRouter {
    method RouterSlices (line 193) | func (h *HeartbeatChecker) RouterSlices() []ziface.RouterHandler {
  type HeatBeatDefaultRouter (line 31) | type HeatBeatDefaultRouter struct
    method Handle (line 35) | func (r *HeatBeatDefaultRouter) Handle(req ziface.IRequest) {
  function HeatBeatDefaultHandle (line 40) | func HeatBeatDefaultHandle(req ziface.IRequest) {
  function makeDefaultMsg (line 45) | func makeDefaultMsg(conn ziface.IConnection) []byte {
  function notAliveDefaultFunc (line 50) | func notAliveDefaultFunc(conn ziface.IConnection) {
  function NewHeartbeatChecker (line 55) | func NewHeartbeatChecker(interval time.Duration) ziface.IHeartbeatChecker {

FILE: znet/kcp_connection.go
  type KcpConnection (line 26) | type KcpConnection struct
    method StartWriter (line 189) | func (c *KcpConnection) StartWriter() {
    method StartReader (line 214) | func (c *KcpConnection) StartReader() {
    method Start (line 277) | func (c *KcpConnection) Start() {
    method Stop (line 314) | func (c *KcpConnection) Stop() {
    method GetConnection (line 318) | func (c *KcpConnection) GetConnection() net.Conn {
    method GetWsConn (line 322) | func (c *KcpConnection) GetWsConn() *websocket.Conn {
    method GetTCPConnection (line 327) | func (c *KcpConnection) GetTCPConnection() net.Conn {
    method GetConnID (line 331) | func (c *KcpConnection) GetConnID() uint64 {
    method GetConnIdStr (line 335) | func (c *KcpConnection) GetConnIdStr() string {
    method GetWorkerID (line 339) | func (c *KcpConnection) GetWorkerID() uint32 {
    method RemoteAddr (line 343) | func (c *KcpConnection) RemoteAddr() net.Addr {
    method LocalAddr (line 347) | func (c *KcpConnection) LocalAddr() net.Addr {
    method Send (line 351) | func (c *KcpConnection) Send(data []byte) error {
    method SendToQueue (line 367) | func (c *KcpConnection) SendToQueue(data []byte, opts ...ziface.MsgSen...
    method SendMsg (line 411) | func (c *KcpConnection) SendMsg(msgID uint32, data []byte) error {
    method SendBuffMsg (line 431) | func (c *KcpConnection) SendBuffMsg(msgID uint32, data []byte, opts .....
    method SetProperty (line 470) | func (c *KcpConnection) SetProperty(key string, value interface{}) {
    method GetProperty (line 480) | func (c *KcpConnection) GetProperty(key string) (interface{}, error) {
    method RemoveProperty (line 491) | func (c *KcpConnection) RemoveProperty(key string) {
    method Context (line 498) | func (c *KcpConnection) Context() context.Context {
    method finalizer (line 502) | func (c *KcpConnection) finalizer() {
    method callOnConnStart (line 551) | func (c *KcpConnection) callOnConnStart() {
    method callOnConnStop (line 558) | func (c *KcpConnection) callOnConnStop() {
    method IsAlive (line 565) | func (c *KcpConnection) IsAlive() bool {
    method updateActivity (line 575) | func (c *KcpConnection) updateActivity() {
    method SetHeartBeat (line 579) | func (c *KcpConnection) SetHeartBeat(checker ziface.IHeartbeatChecker) {
    method LocalAddrString (line 583) | func (c *KcpConnection) LocalAddrString() string {
    method RemoteAddrString (line 587) | func (c *KcpConnection) RemoteAddrString() string {
    method GetName (line 591) | func (c *KcpConnection) GetName() string {
    method GetMsgHandler (line 595) | func (c *KcpConnection) GetMsgHandler() ziface.IMsgHandle {
    method isClosed (line 599) | func (c *KcpConnection) isClosed() bool {
    method setClose (line 603) | func (c *KcpConnection) setClose() bool {
    method AddCloseCallback (line 607) | func (s *KcpConnection) AddCloseCallback(handler, key interface{}, f f...
    method RemoveCloseCallback (line 616) | func (s *KcpConnection) RemoveCloseCallback(handler, key interface{}) {
    method InvokeCloseCallbacks (line 626) | func (s *KcpConnection) InvokeCloseCallbacks() {
  function newKcpServerConn (line 124) | func newKcpServerConn(server ziface.IServer, conn *kcp.UDPSession, connI...
  function newKcpClientConn (line 161) | func newKcpClientConn(client ziface.IClient, conn *kcp.UDPSession) zifac...

FILE: znet/msghandler.go
  constant WorkerIDWithoutWorkerPool (line 18) | WorkerIDWithoutWorkerPool int = 0
  type MsgHandle (line 23) | type MsgHandle struct
    method Intercept (line 255) | func (mh *MsgHandle) Intercept(chain ziface.IChain) ziface.IcResp {
    method SetHeadInterceptor (line 285) | func (mh *MsgHandle) SetHeadInterceptor(interceptor ziface.IIntercepto...
    method AddInterceptor (line 291) | func (mh *MsgHandle) AddInterceptor(interceptor ziface.IInterceptor) {
    method SendMsgToTaskQueue (line 299) | func (mh *MsgHandle) SendMsgToTaskQueue(request ziface.IRequest) {
    method doFuncHandler (line 308) | func (mh *MsgHandle) doFuncHandler(request ziface.IFuncRequest, worker...
    method doMsgHandler (line 320) | func (mh *MsgHandle) doMsgHandler(request ziface.IRequest, workerID in...
    method Execute (line 346) | func (mh *MsgHandle) Execute(request ziface.IRequest) {
    method AddRouter (line 354) | func (mh *MsgHandle) AddRouter(msgID uint32, router ziface.IRouter) {
    method AddRouterSlices (line 369) | func (mh *MsgHandle) AddRouterSlices(msgId uint32, handler ...ziface.R...
    method Group (line 375) | func (mh *MsgHandle) Group(start, end uint32, Handlers ...ziface.Route...
    method Use (line 378) | func (mh *MsgHandle) Use(Handlers ...ziface.RouterHandler) ziface.IRou...
    method doMsgHandlerSlices (line 383) | func (mh *MsgHandle) doMsgHandlerSlices(request ziface.IRequest, worke...
    method StopOneWorker (line 403) | func (mh *MsgHandle) StopOneWorker(workerID int) {
    method StartOneWorker (line 412) | func (mh *MsgHandle) StartOneWorker(workerID int, taskQueue chan zifac...
    method StartWorkerPool (line 447) | func (mh *MsgHandle) StartWorkerPool() {
  function newMsgHandle (line 54) | func newMsgHandle() *MsgHandle {
  function newCliMsgHandle (line 108) | func newCliMsgHandle() *MsgHandle {
  function useWorker (line 162) | func useWorker(conn ziface.IConnection) uint32 {
  function freeWorker (line 221) | func freeWorker(conn ziface.IConnection) {

FILE: znet/options.go
  type Option (line 12) | type Option
  function WithPacket (line 17) | func WithPacket(pack ziface.IDataPack) Option {
  type ClientOption (line 24) | type ClientOption
  function WithPacketClient (line 28) | func WithPacketClient(pack ziface.IDataPack) ClientOption {
  function WithNameClient (line 35) | func WithNameClient(name string) ClientOption {
  function WithUrl (line 41) | func WithUrl(url *url.URL) ClientOption {
  function WithWsHeader (line 48) | func WithWsHeader(header http.Header) ClientOption {

FILE: znet/request.go
  constant PRE_HANDLE (line 13) | PRE_HANDLE  ziface.HandleStep = iota
  constant HANDLE (line 14) | HANDLE
  constant POST_HANDLE (line 15) | POST_HANDLE
  constant HANDLE_OVER (line 17) | HANDLE_OVER
  function init (line 22) | func init() {
  type Request (line 29) | type Request struct
    method GetResponse (line 43) | func (r *Request) GetResponse() ziface.IcResp {
    method SetResponse (line 47) | func (r *Request) SetResponse(response ziface.IcResp) {
    method Reset (line 90) | func (r *Request) Reset(conn ziface.IConnection, msg ziface.IMessage) {
    method Copy (line 103) | func (r *Request) Copy() ziface.IRequest {
    method Set (line 136) | func (r *Request) Set(key string, value interface{}) {
    method Get (line 147) | func (r *Request) Get(key string) (value interface{}, exists bool) {
    method GetMessage (line 154) | func (r *Request) GetMessage() ziface.IMessage {
    method GetConnection (line 158) | func (r *Request) GetConnection() ziface.IConnection {
    method GetData (line 162) | func (r *Request) GetData() []byte {
    method GetMsgID (line 166) | func (r *Request) GetMsgID() uint32 {
    method BindRouter (line 170) | func (r *Request) BindRouter(router ziface.IRouter) {
    method next (line 174) | func (r *Request) next() {
    method Goto (line 185) | func (r *Request) Goto(step ziface.HandleStep) {
    method Call (line 192) | func (r *Request) Call() {
    method Abort (line 214) | func (r *Request) Abort() {
    method BindRouterSlices (line 225) | func (r *Request) BindRouterSlices(handlers []ziface.RouterHandler) {
    method RouterSlicesNext (line 229) | func (r *Request) RouterSlicesNext() {
  function NewRequest (line 51) | func NewRequest(conn ziface.IConnection, msg ziface.IMessage) ziface.IRe...
  function GetRequest (line 62) | func GetRequest(conn ziface.IConnection, msg ziface.IMessage) ziface.IRe...
  function PutRequest (line 75) | func PutRequest(request ziface.IRequest) {
  function allocateRequest (line 82) | func allocateRequest() ziface.IRequest {

FILE: znet/request_func.go
  type RequestFunc (line 5) | type RequestFunc struct
    method GetConnection (line 11) | func (rf *RequestFunc) GetConnection() ziface.IConnection {
    method CallFunc (line 15) | func (rf *RequestFunc) CallFunc() {
  function NewFuncRequest (line 21) | func NewFuncRequest(conn ziface.IConnection, callFunc func()) ziface.IRe...

FILE: znet/router.go
  type BaseRouter (line 13) | type BaseRouter struct
    method PreHandle (line 23) | func (br *BaseRouter) PreHandle(req ziface.IRequest) {}
    method Handle (line 26) | func (br *BaseRouter) Handle(req ziface.IRequest) {}
    method PostHandle (line 29) | func (br *BaseRouter) PostHandle(req ziface.IRequest) {}
  type RouterSlices (line 42) | type RouterSlices struct
    method Use (line 55) | func (r *RouterSlices) Use(handles ...ziface.RouterHandler) {
    method AddHandler (line 59) | func (r *RouterSlices) AddHandler(msgId uint32, Handlers ...ziface.Rou...
    method GetHandlers (line 72) | func (r *RouterSlices) GetHandlers(MsgId uint32) ([]ziface.RouterHandl...
    method Group (line 79) | func (r *RouterSlices) Group(start, end uint32, Handlers ...ziface.Rou...
  function NewRouterSlices (line 48) | func NewRouterSlices() *RouterSlices {
  type GroupRouter (line 83) | type GroupRouter struct
    method Use (line 101) | func (g *GroupRouter) Use(Handlers ...ziface.RouterHandler) {
    method AddHandler (line 105) | func (g *GroupRouter) AddHandler(MsgId uint32, Handlers ...ziface.Rout...
  function NewGroup (line 90) | func NewGroup(start, end uint32, router *RouterSlices, Handlers ...zifac...

FILE: znet/routerSilces_test.go
  function A1 (line 11) | func A1(request ziface.IRequest) {
  function A2 (line 16) | func A2(request ziface.IRequest) {
  function A3 (line 28) | func A3(request ziface.IRequest) {
  function A4 (line 32) | func A4(request ziface.IRequest) {
  function TestRouterAdd (line 37) | func TestRouterAdd(t *testing.T) {

FILE: znet/server.go
  type Server (line 31) | type Server struct
    method StartConn (line 224) | func (s *Server) StartConn(conn ziface.IConnection) {
    method ListenTcpConn (line 238) | func (s *Server) ListenTcpConn() {
    method ListenWebsocketConn (line 316) | func (s *Server) ListenWebsocketConn() {
    method ListenKcpConn (line 374) | func (s *Server) ListenKcpConn() {
    method Start (line 431) | func (s *Server) Start() {
    method Stop (line 460) | func (s *Server) Stop() {
    method Serve (line 471) | func (s *Server) Serve() {
    method AddRouter (line 481) | func (s *Server) AddRouter(msgID uint32, router ziface.IRouter) {
    method AddRouterSlices (line 488) | func (s *Server) AddRouterSlices(msgID uint32, router ...ziface.Router...
    method Group (line 495) | func (s *Server) Group(start, end uint32, Handlers ...ziface.RouterHan...
    method Use (line 502) | func (s *Server) Use(Handlers ...ziface.RouterHandler) ziface.IRouterS...
    method GetConnMgr (line 509) | func (s *Server) GetConnMgr() ziface.IConnManager {
    method SetOnConnStart (line 513) | func (s *Server) SetOnConnStart(hookFunc func(ziface.IConnection)) {
    method SetOnConnStop (line 517) | func (s *Server) SetOnConnStop(hookFunc func(ziface.IConnection)) {
    method GetOnConnStart (line 521) | func (s *Server) GetOnConnStart() func(ziface.IConnection) {
    method GetOnConnStop (line 525) | func (s *Server) GetOnConnStop() func(ziface.IConnection) {
    method GetPacket (line 529) | func (s *Server) GetPacket() ziface.IDataPack {
    method SetPacket (line 533) | func (s *Server) SetPacket(packet ziface.IDataPack) {
    method GetMsgHandler (line 537) | func (s *Server) GetMsgHandler() ziface.IMsgHandle {
    method StartHeartBeat (line 545) | func (s *Server) StartHeartBeat(interval time.Duration) {
    method StartHeartBeatWithOption (line 565) | func (s *Server) StartHeartBeatWithOption(interval time.Duration, opti...
    method GetHeartBeat (line 592) | func (s *Server) GetHeartBeat() ziface.IHeartbeatChecker {
    method SetDecoder (line 596) | func (s *Server) SetDecoder(decoder ziface.IDecoder) {
    method GetLengthField (line 600) | func (s *Server) GetLengthField() *ziface.LengthField {
    method AddInterceptor (line 607) | func (s *Server) AddInterceptor(interceptor ziface.IInterceptor) {
    method SetWebsocketAuth (line 611) | func (s *Server) SetWebsocketAuth(f func(r *http.Request) error) {
    method ServerName (line 615) | func (s *Server) ServerName() string {
  type KcpConfig (line 94) | type KcpConfig struct
  function newServerWithConfig (line 129) | func newServerWithConfig(config *zconf.Config, ipVersion string, opts .....
  function NewServer (line 182) | func NewServer(opts ...Option) ziface.IServer {
  function NewUserConfServer (line 188) | func NewUserConfServer(config *zconf.Config, opts ...Option) ziface.ISer...
  function NewDefaultRouterSlicesServer (line 200) | func NewDefaultRouterSlicesServer(opts ...Option) ziface.IServer {
  function NewUserConfDefaultRouterSlicesServer (line 210) | func NewUserConfDefaultRouterSlicesServer(config *zconf.Config, opts ......
  function init (line 619) | func init() {}

FILE: znet/server_test.go
  function ClientTest (line 21) | func ClientTest(i uint32) {
  type PingRouter (line 77) | type PingRouter struct
    method PreHandle (line 82) | func (this *PingRouter) PreHandle(request ziface.IRequest) {
    method Handle (line 91) | func (this *PingRouter) Handle(request ziface.IRequest) {
    method PostHandle (line 103) | func (this *PingRouter) PostHandle(request ziface.IRequest) {
  type HelloRouter (line 111) | type HelloRouter struct
    method Handle (line 115) | func (this *HelloRouter) Handle(request ziface.IRequest) {
  function DoConnectionBegin (line 125) | func DoConnectionBegin(conn ziface.IConnection) {
  function DoConnectionLost (line 133) | func DoConnectionLost(conn ziface.IConnection) {
  function TestServer (line 137) | func TestServer(t *testing.T) {
  function TestServerDeadLock (line 157) | func TestServerDeadLock(t *testing.T) {
  type CloseConnectionBeforeSendMsgRouter (line 170) | type CloseConnectionBeforeSendMsgRouter struct
    method Handle (line 183) | func (br *CloseConnectionBeforeSendMsgRouter) Handle(req ziface.IReque...
  type DemoPacket (line 174) | type DemoPacket struct
    method Pack (line 178) | func (d *DemoPacket) Pack(msg ziface.IMessage) ([]byte, error) {
  function TestCloseConnectionBeforeSendMsg (line 191) | func TestCloseConnectionBeforeSendMsg(t *testing.T) {

FILE: znet/ws_connection.go
  type WsConnectionHttpReqCtxKey (line 22) | type WsConnectionHttpReqCtxKey struct
  type WsConnection (line 26) | type WsConnection struct
    method StartWriter (line 185) | func (c *WsConnection) StartWriter() {
    method StartReader (line 210) | func (c *WsConnection) StartReader() {
    method Start (line 276) | func (c *WsConnection) Start() {
    method Stop (line 312) | func (c *WsConnection) Stop() {
    method GetConnection (line 316) | func (c *WsConnection) GetConnection() net.Conn {
    method GetWsConn (line 320) | func (c *WsConnection) GetWsConn() *websocket.Conn {
    method GetTCPConnection (line 325) | func (c *WsConnection) GetTCPConnection() net.Conn {
    method GetConnID (line 329) | func (c *WsConnection) GetConnID() uint64 {
    method GetConnIdStr (line 333) | func (c *WsConnection) GetConnIdStr() string {
    method GetWorkerID (line 337) | func (c *WsConnection) GetWorkerID() uint32 {
    method RemoteAddr (line 341) | func (c *WsConnection) RemoteAddr() net.Addr {
    method LocalAddr (line 345) | func (c *WsConnection) LocalAddr() net.Addr {
    method Send (line 349) | func (c *WsConnection) Send(data []byte) error {
    method SendToQueue (line 365) | func (c *WsConnection) SendToQueue(data []byte, opts ...ziface.MsgSend...
    method SendMsg (line 408) | func (c *WsConnection) SendMsg(msgID uint32, data []byte) error {
    method SendBuffMsg (line 434) | func (c *WsConnection) SendBuffMsg(msgID uint32, data []byte, opts ......
    method SetProperty (line 479) | func (c *WsConnection) SetProperty(key string, value interface{}) {
    method GetProperty (line 489) | func (c *WsConnection) GetProperty(key string) (interface{}, error) {
    method RemoveProperty (line 500) | func (c *WsConnection) RemoveProperty(key string) {
    method Context (line 509) | func (c *WsConnection) Context() context.Context {
    method finalizer (line 513) | func (c *WsConnection) finalizer() {
    method callOnConnStart (line 565) | func (c *WsConnection) callOnConnStart() {
    method callOnConnStop (line 572) | func (c *WsConnection) callOnConnStop() {
    method IsAlive (line 579) | func (c *WsConnection) IsAlive() bool {
    method updateActivity (line 589) | func (c *WsConnection) updateActivity() {
    method SetHeartBeat (line 593) | func (c *WsConnection) SetHeartBeat(checker ziface.IHeartbeatChecker) {
    method LocalAddrString (line 597) | func (c *WsConnection) LocalAddrString() string {
    method RemoteAddrString (line 601) | func (c *WsConnection) RemoteAddrString() string {
    method GetName (line 605) | func (c *WsConnection) GetName() string {
    method GetMsgHandler (line 609) | func (c *WsConnection) GetMsgHandler() ziface.IMsgHandle {
    method AddCloseCallback (line 613) | func (s *WsConnection) AddCloseCallback(handler, key interface{}, f fu...
    method RemoveCloseCallback (line 622) | func (s *WsConnection) RemoveCloseCallback(handler, key interface{}) {
    method InvokeCloseCallbacks (line 631) | func (s *WsConnection) InvokeCloseCallbacks() {
  function newWebsocketConn (line 119) | func newWebsocketConn(server ziface.IServer, conn *websocket.Conn, connI...
  function newWsClientConn (line 156) | func newWsClientConn(client ziface.IClient, conn *websocket.Conn) ziface...

FILE: znotify/notify.go
  type notify (line 20) | type notify struct
    method genConnStrId (line 30) | func (n *notify) genConnStrId(connID uint64) string {
    method ConnNums (line 35) | func (n *notify) ConnNums() int {
    method HasIdConn (line 39) | func (n *notify) HasIdConn(Id uint64) bool {
    method SetNotifyID (line 44) | func (n *notify) SetNotifyID(Id uint64, conn ziface.IConnection) {
    method GetNotifyByID (line 49) | func (n *notify) GetNotifyByID(Id uint64) (ziface.IConnection, error) {
    method DelNotifyByID (line 59) | func (n *notify) DelNotifyByID(Id uint64) {
    method NotifyToConnByID (line 64) | func (n *notify) NotifyToConnByID(Id uint64, MsgId uint32, data []byte...
    method NotifyAll (line 77) | func (n *notify) NotifyAll(MsgId uint32, data []byte) error {
    method NotifyBuffToConnByID (line 90) | func (n *notify) NotifyBuffToConnByID(Id uint64, MsgId uint32, data []...
    method NotifyBuffAll (line 103) | func (n *notify) NotifyBuffAll(MsgId uint32, data []byte) error {
  function NewZNotify (line 24) | func NewZNotify() ziface.Inotify {

FILE: znotify/notify_test.go
  type router (line 18) | type router struct
    method Handle (line 22) | func (r *router) Handle(req ziface.IRequest) {
  function Server (line 27) | func Server() {
  function Clinet (line 44) | func Clinet() {
  function ClientJoin (line 72) | func ClientJoin() {
  function TestAA (line 105) | func TestAA(t *testing.T) {
  function BenchmarkNotify (line 112) | func BenchmarkNotify(b *testing.B) {
  function init (line 122) | func init() {

FILE: zpack/datapack_ltv_littleendian.go
  type DataPackLtv (line 15) | type DataPackLtv struct
    method GetHeadLen (line 25) | func (dp *DataPackLtv) GetHeadLen() uint32 {
    method Pack (line 32) | func (dp *DataPackLtv) Pack(msg ziface.IMessage) ([]byte, error) {
    method Unpack (line 57) | func (dp *DataPackLtv) Unpack(binaryData []byte) (ziface.IMessage, err...
  function NewDataPackLtv (line 19) | func NewDataPackLtv() ziface.IDataPack {

FILE: zpack/datapack_tlv_bigendian.go
  type DataPack (line 14) | type DataPack struct
    method GetHeadLen (line 24) | func (dp *DataPack) GetHeadLen() uint32 {
    method Pack (line 31) | func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
    method Unpack (line 56) | func (dp *DataPack) Unpack(binaryData []byte) (ziface.IMessage, error) {
  function NewDataPack (line 18) | func NewDataPack() ziface.IDataPack {

FILE: zpack/datapack_tlv_bigendian_test.go
  function TestDataPack (line 17) | func TestDataPack(t *testing.T) {

FILE: zpack/message.go
  type Message (line 4) | type Message struct
    method Init (line 37) | func (msg *Message) Init(ID uint32, data []byte) {
    method GetDataLen (line 44) | func (msg *Message) GetDataLen() uint32 {
    method GetMsgID (line 48) | func (msg *Message) GetMsgID() uint32 {
    method GetData (line 52) | func (msg *Message) GetData() []byte {
    method GetRawData (line 56) | func (msg *Message) GetRawData() []byte {
    method SetDataLen (line 60) | func (msg *Message) SetDataLen(len uint32) {
    method SetMsgID (line 64) | func (msg *Message) SetMsgID(msgID uint32) {
    method SetData (line 68) | func (msg *Message) SetData(data []byte) {
  function NewMsgPackage (line 11) | func NewMsgPackage(ID uint32, data []byte) *Message {
  function NewMessage (line 20) | func NewMessage(len uint32, data []byte) *Message {
  function NewMessageByMsgId (line 28) | func NewMessageByMsgId(id uint32, len uint32, data []byte) *Message {

FILE: zpack/packfactory.go
  type pack_factory (line 11) | type pack_factory struct
    method NewPack (line 30) | func (f *pack_factory) NewPack(kind string) ziface.IDataPack {
  function Factory (line 20) | func Factory() *pack_factory {

FILE: ztimer/delayfunc.go
  type DelayFunc (line 22) | type DelayFunc struct
    method String (line 36) | func (df *DelayFunc) String() string {
    method Call (line 41) | func (df *DelayFunc) Call() {
  function NewDelayFunc (line 28) | func NewDelayFunc(f func(v ...interface{}), args []interface{}) *DelayFu...

FILE: ztimer/delayfunc_test.go
  function SayHello (line 15) | func SayHello(message ...interface{}) {
  function TestDelayfunc (line 19) | func TestDelayfunc(t *testing.T) {

FILE: ztimer/timer.go
  constant HourName (line 15) | HourName = "HOUR"
  constant HourInterval (line 17) | HourInterval = 60 * 60 * 1e3
  constant HourScales (line 19) | HourScales = 12
  constant MinuteName (line 22) | MinuteName = "MINUTE"
  constant MinuteInterval (line 24) | MinuteInterval = 60 * 1e3
  constant MinuteScales (line 26) | MinuteScales = 60
  constant SecondName (line 29) | SecondName = "SECOND"
  constant SecondInterval (line 31) | SecondInterval = 1e3
  constant SecondScales (line 33) | SecondScales = 60
  constant TimersMaxCap (line 35) | TimersMaxCap = 2048
  type Timer (line 49) | type Timer struct
    method Run (line 75) | func (t *Timer) Run() {
  function UnixMilli (line 57) | func UnixMilli() int64 {
  function NewTimerAt (line 62) | func NewTimerAt(df *DelayFunc, unixNano int64) *Timer {
  function NewTimerAfter (line 70) | func NewTimerAfter(df *DelayFunc, duration time.Duration) *Timer {

FILE: ztimer/timer_test.go
  function myFunc (line 17) | func myFunc(v ...interface{}) {
  function TestTimer (line 21) | func TestTimer(t *testing.T) {

FILE: ztimer/timerscheduler.go
  constant MaxChanBuff (line 22) | MaxChanBuff = 2048
  constant MaxTimeDelay (line 24) | MaxTimeDelay = 100
  type TimerScheduler (line 28) | type TimerScheduler struct
    method CreateTimerAt (line 65) | func (ts *TimerScheduler) CreateTimerAt(df *DelayFunc, unixNano int64)...
    method CreateTimerAfter (line 74) | func (ts *TimerScheduler) CreateTimerAfter(df *DelayFunc, duration tim...
    method CancelTimer (line 83) | func (ts *TimerScheduler) CancelTimer(tID uint32) {
    method GetTriggerChan (line 95) | func (ts *TimerScheduler) GetTriggerChan() chan *DelayFunc {
    method Start (line 100) | func (ts *TimerScheduler) Start() {
  function NewTimerScheduler (line 40) | func NewTimerScheduler() *TimerScheduler {
  function NewAutoExecTimerScheduler (line 120) | func NewAutoExecTimerScheduler() *TimerScheduler {

FILE: ztimer/timerscheduler_test.go
  function foo (line 21) | func foo(args ...interface{}) {
  function TestNewTimerScheduler (line 26) | func TestNewTimerScheduler(t *testing.T) {
  function TestNewAutoExecTimerScheduler (line 53) | func TestNewAutoExecTimerScheduler(t *testing.T) {
  function TestCancelTimerScheduler (line 71) | func TestCancelTimerScheduler(t *testing.T) {

FILE: ztimer/timewheel.go
  type TimeWheel (line 30) | type TimeWheel struct
    method addTimer (line 85) | func (tw *TimeWheel) addTimer(tID uint32, t *Timer, forceNext bool) er...
    method AddTimer (line 133) | func (tw *TimeWheel) AddTimer(tID uint32, t *Timer) error {
    method RemoveTimer (line 141) | func (tw *TimeWheel) RemoveTimer(tID uint32) {
    method AddTimeWheel (line 153) | func (tw *TimeWheel) AddTimeWheel(next *TimeWheel) {
    method run (line 161) | func (tw *TimeWheel) run() {
    method Run (line 191) | func (tw *TimeWheel) Run() {
    method GetTimerWithIn (line 197) | func (tw *TimeWheel) GetTimerWithIn(duration time.Duration) map[uint32...
  function NewTimeWheel (line 51) | func NewTimeWheel(name string, interval int64, scales int, maxCap int) *...

FILE: ztimer/timewheel_test.go
  function TestTimerWheel (line 17) | func TestTimerWheel(t *testing.T) {

FILE: zutils/hash.go
  constant Prime (line 4) | Prime   = 16777619
  constant HashVal (line 5) | HashVal = 2166136261
  type IHash (line 8) | type IHash interface
  type Fnv32Hash (line 12) | type Fnv32Hash struct
    method Sum (line 19) | func (f *Fnv32Hash) Sum(key string) uint32 {
  function DefaultHash (line 14) | func DefaultHash() IHash {

FILE: zutils/shard_lock_map.go
  type ShardLockMaps (line 18) | type ShardLockMaps struct
    method GetShard (line 76) | func (slm ShardLockMaps) GetShard(key string) *SingleShardMap {
    method Count (line 81) | func (slm ShardLockMaps) Count() int {
    method Get (line 93) | func (slm ShardLockMaps) Get(key string) (interface{}, bool) {
    method Set (line 102) | func (slm ShardLockMaps) Set(key string, value interface{}) {
    method SetNX (line 110) | func (slm ShardLockMaps) SetNX(key string, value interface{}) bool {
    method MSet (line 122) | func (slm ShardLockMaps) MSet(data map[string]interface{}) {
    method Has (line 132) | func (slm ShardLockMaps) Has(key string) bool {
    method Remove (line 141) | func (slm ShardLockMaps) Remove(key string) {
    method RemoveCb (line 155) | func (slm ShardLockMaps) RemoveCb(key string, cb RemoveCb) bool {
    method Pop (line 169) | func (slm ShardLockMaps) Pop(key string) (v interface{}, exists bool) {
    method GetOrSet (line 180) | func (slm ShardLockMaps) GetOrSet(key string, value interface{}) (inte...
    method GetOrSetFunc (line 190) | func (slm ShardLockMaps) GetOrSetFunc(key string, f func(key string) i...
    method GetOrSetFuncLock (line 201) | func (slm ShardLockMaps) GetOrSetFuncLock(key string, f func(key strin...
    method doSetWithLockCheck (line 209) | func (slm ShardLockMaps) doSetWithLockCheck(key string, val interface{...
    method doSetWithLockCheckWithFunc (line 223) | func (slm ShardLockMaps) doSetWithLockCheckWithFunc(key string, f func...
    method Clear (line 238) | func (slm ShardLockMaps) Clear() {
    method LockFuncWithKey (line 246) | func (slm ShardLockMaps) LockFuncWithKey(key string, f func(shardData ...
    method RLockFuncWithKey (line 255) | func (slm ShardLockMaps) RLockFuncWithKey(key string, f func(shardData...
    method LockFunc (line 264) | func (slm ShardLockMaps) LockFunc(f func(shardData map[string]interfac...
    method RLockFunc (line 274) | func (slm ShardLockMaps) RLockFunc(f func(shardData map[string]interfa...
    method ClearWithFuncLock (line 284) | func (slm ShardLockMaps) ClearWithFuncLock(onClear func(key string, va...
    method IsEmpty (line 296) | func (slm ShardLockMaps) IsEmpty() bool {
    method MGet (line 301) | func (slm ShardLockMaps) MGet(keys ...string) map[string]interface{} {
    method GetAll (line 312) | func (slm ShardLockMaps) GetAll() map[string]interface{} {
    method IterBuffered (line 371) | func (slm ShardLockMaps) IterBuffered() <-chan Tuple {
    method Items (line 383) | func (slm ShardLockMaps) Items() map[string]interface{} {
    method Keys (line 394) | func (slm ShardLockMaps) Keys() []string {
    method IterCb (line 429) | func (slm ShardLockMaps) IterCb(fn IterCb) {
    method MarshalJSON (line 441) | func (slm ShardLockMaps) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 451) | func (slm ShardLockMaps) UnmarshalJSON(b []byte) (err error) {
  type SingleShardMap (line 26) | type SingleShardMap struct
  function createShardLockMaps (line 32) | func createShardLockMaps(hash IHash, shardCount int) ShardLockMaps {
  function NewShardLockMaps (line 52) | func NewShardLockMaps() ShardLockMaps {
  function NewShardLockMapsWithCount (line 59) | func NewShardLockMapsWithCount(shardCount int) ShardLockMaps {
  function NewWithCustomHash (line 65) | func NewWithCustomHash(hash IHash) ShardLockMaps {
  function NewWithCustomHashAndCount (line 71) | func NewWithCustomHashAndCount(hash IHash, shardCount int) ShardLockMaps {
  type RemoveCb (line 150) | type RemoveCb
  type Tuple (line 325) | type Tuple struct
  function snapshot (line 334) | func snapshot(slm ShardLockMaps) (chanList []chan Tuple) {
  function fanIn (line 355) | func fanIn(chanList []chan Tuple, out chan Tuple) {
  type IterCb (line 425) | type IterCb

FILE: zutils/shard_lock_map_bench_test.go
  function BenchmarkItems (line 9) | func BenchmarkItems(b *testing.B) {
  function BenchmarkKeys (line 20) | func BenchmarkKeys(b *testing.B) {
  function BenchmarkMarshalJson (line 31) | func BenchmarkMarshalJson(b *testing.B) {
  function BenchmarkStrconv (line 45) | func BenchmarkStrconv(b *testing.B) {
  function BenchmarkSingleInsertAbsent (line 51) | func BenchmarkSingleInsertAbsent(b *testing.B) {
  function BenchmarkSingleInsertAbsentSyncMap (line 59) | func BenchmarkSingleInsertAbsentSyncMap(b *testing.B) {
  function BenchmarkSingleInsertPresent (line 67) | func BenchmarkSingleInsertPresent(b *testing.B) {
  function BenchmarkSingleInsertPresentSyncMap (line 76) | func BenchmarkSingleInsertPresentSyncMap(b *testing.B) {
  function BenchmarkMultiInsertDifferentSyncMap (line 85) | func BenchmarkMultiInsertDifferentSyncMap(b *testing.B) {
  function BenchmarkMultiInsertDifferent_1_Shard (line 99) | func BenchmarkMultiInsertDifferent_1_Shard(b *testing.B) {
  function BenchmarkMultiInsertDifferent_16_Shard (line 103) | func BenchmarkMultiInsertDifferent_16_Shard(b *testing.B) {
  function BenchmarkMultiInsertDifferent_32_Shard (line 107) | func BenchmarkMultiInsertDifferent_32_Shard(b *testing.B) {
  function BenchmarkMultiInsertDifferent_256_Shard (line 111) | func BenchmarkMultiInsertDifferent_256_Shard(b *testing.B) {
  function BenchmarkMultiInsertSame (line 116) | func BenchmarkMultiInsertSame(b *testing.B) {
  function BenchmarkMultiInsertSameSyncMap (line 130) | func BenchmarkMultiInsertSameSyncMap(b *testing.B) {
  function BenchmarkMultiGetSame (line 144) | func BenchmarkMultiGetSame(b *testing.B) {
  function BenchmarkMultiGetSameSyncMap (line 158) | func BenchmarkMultiGetSameSyncMap(b *testing.B) {
  function BenchmarkMultiGetSetDifferentSyncMap (line 172) | func BenchmarkMultiGetSetDifferentSyncMap(b *testing.B) {
  function BenchmarkMultiGetSetDifferent_1_Shard (line 187) | func BenchmarkMultiGetSetDifferent_1_Shard(b *testing.B) {
  function BenchmarkMultiGetSetDifferent_16_Shard (line 191) | func BenchmarkMultiGetSetDifferent_16_Shard(b *testing.B) {
  function BenchmarkMultiGetSetDifferent_32_Shard (line 195) | func BenchmarkMultiGetSetDifferent_32_Shard(b *testing.B) {
  function BenchmarkMultiGetSetDifferent_256_Shard (line 199) | func BenchmarkMultiGetSetDifferent_256_Shard(b *testing.B) {
  function BenchmarkMultiGetSetBlockSyncMap (line 204) | func BenchmarkMultiGetSetBlockSyncMap(b *testing.B) {
  function BenchmarkMultiGetSetBlock_1_Shard (line 221) | func BenchmarkMultiGetSetBlock_1_Shard(b *testing.B) {
  function BenchmarkMultiGetSetBlock_16_Shard (line 225) | func BenchmarkMultiGetSetBlock_16_Shard(b *testing.B) {
  function BenchmarkMultiGetSetBlock_32_Shard (line 229) | func BenchmarkMultiGetSetBlock_32_Shard(b *testing.B) {
  function BenchmarkMultiGetSetBlock_256_Shard (line 233) | func BenchmarkMultiGetSetBlock_256_Shard(b *testing.B) {
  function benchmarkMultiInsertDifferent (line 238) | func benchmarkMultiInsertDifferent(b *testing.B) {
  function benchmarkMultiGetSetDifferent (line 251) | func benchmarkMultiGetSetDifferent(b *testing.B) {
  function benchmarkMultiGetSetBlock (line 266) | func benchmarkMultiGetSetBlock(b *testing.B) {
  function GetSet (line 283) | func GetSet(slm ShardLockMaps, finished chan struct{}) (set func(key, va...
  function GetSetSyncMap (line 297) | func GetSetSyncMap(m *sync.Map, finished chan struct{}) (get func(key, v...
  function benchmarkMultiInsertDifferentWithMap (line 313) | func benchmarkMultiInsertDifferentWithMap(slm ShardLockMaps, b *testing....
  function benchmarkMultiGetSetDifferentWithMap (line 324) | func benchmarkMultiGetSetDifferentWithMap(slm ShardLockMaps, b *testing....
  function benchmarkMultiGetSetBlockWithMap (line 336) | func benchmarkMultiGetSetBlockWithMap(slm ShardLockMaps, b *testing.B) {

FILE: zutils/shard_lock_map_test.go
  type TestUser (line 11) | type TestUser struct
  function TestCreatMap (line 15) | func TestCreatMap(t *testing.T) {
  function TestSet (line 26) | func TestSet(t *testing.T) {
  function TestGet (line 44) | func TestGet(t *testing.T) {
  function TestHas (line 76) | func TestHas(t *testing.T) {
  function TestCount (line 91) | func TestCount(t *testing.T) {
  function TestRemove (line 103) | func TestRemove(t *testing.T) {
  function TestRemoveCb (line 134) | func TestRemoveCb(t *testing.T) {
  function TestPop (line 222) | func TestPop(t *testing.T) {
  function TestBufferedIterator (line 239) | func TestBufferedIterator(t *testing.T) {
  function TestClear (line 262) | func TestClear(t *testing.T) {
  function TestIterCb (line 276) | func TestIterCb(t *testing.T) {
  function TestItems (line 297) | func TestItems(t *testing.T) {
  function TestJsonMarshal (line 312) | func TestJsonMarshal(t *testing.T) {
  function TestUnmarshalJSON (line 328) | func TestUnmarshalJSON(t *testing.T) {
  function TestKeys (line 347) | func TestKeys(t *testing.T) {
  function TestFnv32 (line 360) | func TestFnv32(t *testing.T) {
  function TestKeysWhenRemoving (line 374) | func TestKeysWhenRemoving(t *testing.T) {
  function TestUnDrainedIterBuffered (line 396) | func TestUnDrainedIterBuffered(t *testing.T) {
  function TestConcurrent (line 449) | func TestConcurrent(t *testing.T) {
  function TestGetOrSet (line 509) | func TestGetOrSet(t *testing.T) {
  function TestGetOrSetFunc (line 532) | func TestGetOrSetFunc(t *testing.T) {
  function TestGetOrSetFuncLock (line 559) | func TestGetOrSetFuncLock(t *testing.T) {
  function TestMGet (line 586) | func TestMGet(t *testing.T) {
  function TestGetAll (line 612) | func TestGetAll(t *testing.T) {
  function TestLockFuncWithKey (line 627) | func TestLockFuncWithKey(t *testing.T) {
  function TestRLockFuncWithKey (line 646) | func TestRLockFuncWithKey(t *testing.T) {
  function TestLockFunc (line 665) | func TestLockFunc(t *testing.T) {
  function TestRLockFunc (line 687) | func TestRLockFunc(t *testing.T) {
  function TestClearWithFuncLock (line 704) | func TestClearWithFuncLock(t *testing.T) {

FILE: zutils/snowflake_uuid.go
  constant workerBits (line 18) | workerBits     uint8 = 10
  constant maxWorker (line 19) | maxWorker      int64 = -1 ^ (-1 << workerBits)
  constant sequenceBits (line 20) | sequenceBits   uint8 = 12
  constant sequenceMask (line 21) | sequenceMask   int64 = -1 ^ (-1 << sequenceBits)
  constant workerShift (line 22) | workerShift    uint8 = sequenceBits
  constant timestampShift (line 23) | timestampShift uint8 = sequenceBits + workerBits
  type IDWorker (line 26) | type IDWorker struct
    method NextID (line 45) | func (w *IDWorker) NextID() (int64, error) {
    method nextMillisecond (line 69) | func (w *IDWorker) nextMillisecond(currentTimestamp int64) int64 {
  function NewIDWorker (line 33) | func NewIDWorker(workerId int64) (*IDWorker, error) {

FILE: zutils/snowflake_uuid_test.go
  function TestSnowFlakeUUID (line 8) | func TestSnowFlakeUUID(t *testing.T) {

FILE: zutils/witer.go
  constant sizeMiB (line 18) | sizeMiB    = 1024 * 1024
  constant defMaxAge (line 19) | defMaxAge  = 31
  constant defMaxSize (line 20) | defMaxSize = 64
  type Writer (line 25) | type Writer struct
    method daemon (line 62) | func (w *Writer) daemon() {
    method SetMaxAge (line 69) | func (w *Writer) SetMaxAge(ma int) {
    method SetMaxSize (line 76) | func (w *Writer) SetMaxSize(ms int64) {
    method SetCons (line 86) | func (w *Writer) SetCons(b bool) {
    method Write (line 92) | func (w *Writer) Write(p []byte) (n int, err error) {
    method rotate (line 131) | func (w *Writer) rotate() error {
    method delete (line 169) | func (w *Writer) delete() {
    method name2time (line 192) | func (w *Writer) name2time(name string) (time.Time, error) {
    method time2name (line 198) | func (w *Writer) time2name(t time.Time) string {
    method Close (line 202) | func (w *Writer) Close() error {
    method close (line 208) | func (w *Writer) close() error {
    method flush (line 220) | func (w *Writer) flush() error {
  function New (line 42) | func New(path string) *Writer {
  function ZipToFile (line 233) | func ZipToFile(dst, src string) error {
  function Zip (line 248) | func Zip(dst io.Writer, src string) error {
Condensed preview — 233 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (604K chars).
[
  {
    "path": ".gitattributes",
    "chars": 28,
    "preview": "*.aspx linguist-language=Go\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 913,
    "preview": "# These are supported funding model platforms\n\ngithub: [aceld] # Replace with up to 4 GitHub Sponsors-enabled usernames "
  },
  {
    "path": ".github/workflows/reviewdog.yml",
    "chars": 817,
    "preview": "name: reviewdog\non: [pull_request]\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  golangci-lint:\n    run"
  },
  {
    "path": ".gitignore",
    "chars": 329,
    "preview": ".idea\n.vscode\n\n/zinx_app_demo/mmo_game/game_client/client_Data/\n/zinx_app_demt/mmo_game/mmo_game_log/\n*.log\n\n### bin\nexa"
  },
  {
    "path": ".golangci.yaml",
    "chars": 333,
    "preview": "run:\n  timeout: 30m\n  skip-dirs:\n  - examples\n\nlinters:\n  disable-all: true\n  enable:\n  #- unused\n  - ineffassign\n  - go"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2024 Aceld(刘丹冰)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "Makefile",
    "chars": 1094,
    "preview": "\n.PHONY: build\n\nSERVICE := zinx\nCUR_PWD := $(shell pwd)\n\nSERVER_DEMO_PATH := $(CUR_PWD)/examples/zinx_server\nCLIENT_DEMO"
  },
  {
    "path": "README-CN.md",
    "chars": 10611,
    "preview": "# <img width=\"80px\" src=\"https://s2.ax1x.com/2019/10/09/u4yHo9.png\" /> \n\n[English](README.md) | 简体中文\n\n[![License](https:"
  },
  {
    "path": "README.md",
    "chars": 12338,
    "preview": "# <img width=\"80px\" src=\"https://s2.ax1x.com/2019/10/09/u4yHo9.png\" />\nEnglish | [简体中文](README-CN.md)\n\n[![License](https"
  },
  {
    "path": "examples/zinx_RequestPollMode/client/client.go",
    "chars": 2152,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"githu"
  },
  {
    "path": "examples/zinx_RequestPollMode/no_pool_mode_server/NoPoolModeServer.go",
    "chars": 746,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/zconf\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld"
  },
  {
    "path": "examples/zinx_RequestPollMode/pool_mode_server/PoolModeServer.go",
    "chars": 1436,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/zconf\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld"
  },
  {
    "path": "examples/zinx_async_op/async_op_apis/user_async_api.go",
    "chars": 690,
    "preview": "package async_op_apis\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_async_op/db_model\"\n\t\"github.com/aceld/zinx/zasync_"
  },
  {
    "path": "examples/zinx_async_op/client/client.go",
    "chars": 1057,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\n\t\"github.com/aceld/zinx/zpack\"\n)\n\nfunc main() {\n\tconn, err := net.Dial(\"tcp\""
  },
  {
    "path": "examples/zinx_async_op/db_model/user_dao.go",
    "chars": 406,
    "preview": "package db_model\n\nimport (\n\t\"time\"\n\n\t\"github.com/aceld/zinx/zlog\"\n)\n\ntype UserModel struct {\n\tUserId     uint32\n\tUpdateT"
  },
  {
    "path": "examples/zinx_async_op/msg_struct/user_login.go",
    "chars": 104,
    "preview": "package msg_struct\n\ntype MsgLoginResponse struct {\n\tUserId    uint32\n\tUserName  string\n\tErrorCode int\n}\n"
  },
  {
    "path": "examples/zinx_async_op/router/login.go",
    "chars": 1967,
    "preview": "package router\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/examples/zinx_async_op/async_op_apis\"\n\t\"githu"
  },
  {
    "path": "examples/zinx_async_op/server/server.go",
    "chars": 539,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_async_op/router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.c"
  },
  {
    "path": "examples/zinx_client/Makefile",
    "chars": 268,
    "preview": "PROJECT_NAME:=zinx_client\nVERSION:=v1\n\n\n.PHONY: image run build clean\n\nbuild:\n\tbash build.sh ${PROJECT_NAME}\n\nimage:\n\tdo"
  },
  {
    "path": "examples/zinx_client/build.sh",
    "chars": 581,
    "preview": "#!/bin/bash\n\nset -e\n\nAPP_NAME=$1\nAPP_VERSION=v$(cat version)\nBUILD_VERSION=$(git log -1 --oneline)\nBUILD_TIME=$(date \"+%"
  },
  {
    "path": "examples/zinx_client/c_router/hello.go",
    "chars": 398,
    "preview": "package c_router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)"
  },
  {
    "path": "examples/zinx_client/c_router/ping.go",
    "chars": 524,
    "preview": "package c_router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)"
  },
  {
    "path": "examples/zinx_client/main.go",
    "chars": 2133,
    "preview": "/**\n* @Author: Aceld\n* @Date: 2023/03/02\n* @Mail: danbing.at@gmail.com\n*    zinx client demo\n */\npackage main\n\nimport (\n"
  },
  {
    "path": "examples/zinx_client/version",
    "chars": 8,
    "preview": "v 1.0.0\n"
  },
  {
    "path": "examples/zinx_client_old/Makefile",
    "chars": 268,
    "preview": "PROJECT_NAME:=zinx_client\nVERSION:=v1\n\n\n.PHONY: image run build clean\n\nbuild:\n\tbash build.sh ${PROJECT_NAME}\n\nimage:\n\tdo"
  },
  {
    "path": "examples/zinx_client_old/build.sh",
    "chars": 581,
    "preview": "#!/bin/bash\n\nset -e\n\nAPP_NAME=$1\nAPP_VERSION=v$(cat version)\nBUILD_VERSION=$(git log -1 --oneline)\nBUILD_TIME=$(date \"+%"
  },
  {
    "path": "examples/zinx_client_old/c_router/hello.go",
    "chars": 398,
    "preview": "package c_router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)"
  },
  {
    "path": "examples/zinx_client_old/c_router/ping.go",
    "chars": 515,
    "preview": "package c_router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)"
  },
  {
    "path": "examples/zinx_client_old/main.go",
    "chars": 1177,
    "preview": "/**\n* @Author: Aceld\n* @Date: 2023/03/02\n* @Mail: danbing.at@gmail.com\n*    zinx client demo\n */\npackage main\n\nimport (\n"
  },
  {
    "path": "examples/zinx_client_old/version",
    "chars": 8,
    "preview": "v 1.0.0\n"
  },
  {
    "path": "examples/zinx_closecallback/client/client.go",
    "chars": 2025,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/examples/zinx_closecallback/router\"\n\t\""
  },
  {
    "path": "examples/zinx_closecallback/router/ping_router.go",
    "chars": 776,
    "preview": "package router\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// PingRouter handles "
  },
  {
    "path": "examples/zinx_closecallback/server/server.go",
    "chars": 1720,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/examples/zinx_closecallback/router\"\n\t\"github.com/aceld/zi"
  },
  {
    "path": "examples/zinx_decoder/README.MD",
    "chars": 6521,
    "preview": "# LengthFieldFrameDecoder使用详解\n\n\n>LengthFieldFrameDecoder是一个基于长度字段的解码器,比较难理解的解码器,它主要有5个核心的参数配置:\n\n>maxFrameLength:     数据包"
  },
  {
    "path": "examples/zinx_decoder/bili/README.MD",
    "chars": 729,
    "preview": "# 一款水机设备服务端模拟程序\n\n\n```shell\nHTLV+CRC,H头码,T功能码,L数据长度,V数据内容\n+------+-------+---------+--------+--------+\n| 头码  | 功能码 | 数据长度"
  },
  {
    "path": "examples/zinx_decoder/bili/main.go",
    "chars": 982,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_decoder/bili/router\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"gi"
  },
  {
    "path": "examples/zinx_decoder/bili/router/bili0x10router.go",
    "chars": 2246,
    "preview": "package router\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"gi"
  },
  {
    "path": "examples/zinx_decoder/bili/router/bili0x13router.go",
    "chars": 1858,
    "preview": "package router\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/"
  },
  {
    "path": "examples/zinx_decoder/bili/router/bili0x14router.go",
    "chars": 1067,
    "preview": "package router\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/"
  },
  {
    "path": "examples/zinx_decoder/bili/router/bili0x15router.go",
    "chars": 8444,
    "preview": "package router\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/"
  },
  {
    "path": "examples/zinx_decoder/bili/router/bili0x16router.go",
    "chars": 1117,
    "preview": "package router\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/"
  },
  {
    "path": "examples/zinx_decoder/client/client.go",
    "chars": 3616,
    "preview": "package main\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/zif"
  },
  {
    "path": "examples/zinx_decoder/router/htlvcrcbusinessrouter.go",
    "chars": 644,
    "preview": "package router\n\nimport (\n\t\"encoding/hex\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/"
  },
  {
    "path": "examples/zinx_decoder/router/tlvbusinessrouter.go",
    "chars": 581,
    "preview": "package router\n\nimport (\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\""
  },
  {
    "path": "examples/zinx_decoder/server/server.go",
    "chars": 1190,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_decoder/router\"\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github."
  },
  {
    "path": "examples/zinx_dynamic_bind/client/client.go",
    "chars": 2275,
    "preview": "package main\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"githu"
  },
  {
    "path": "examples/zinx_dynamic_bind/server/conf/zinx.json",
    "chars": 200,
    "preview": "{\n    \"Name\":\"zinx server DynamicBind Mode Demo\",\n    \"Host\":\"127.0.0.1\",\n    \"TCPPort\":8999,\n    \"MaxConn\":12000,\n    \""
  },
  {
    "path": "examples/zinx_dynamic_bind/server/server.go",
    "chars": 1486,
    "preview": "package main\n\nimport (\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.co"
  },
  {
    "path": "examples/zinx_heartbeat/client/client.go",
    "chars": 1279,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n\t\"time\"\n)\n\n// User-defined h"
  },
  {
    "path": "examples/zinx_heartbeat/client_default/client_default.go",
    "chars": 239,
    "preview": "package main\n\nimport (\n\t\"time\"\n\n\t\"github.com/aceld/zinx/znet\"\n)\n\nfunc main() {\n\tclient := znet.NewClient(\"127.0.0.1\", 89"
  },
  {
    "path": "examples/zinx_heartbeat/server/conf/zinx.json",
    "chars": 156,
    "preview": "{\n  \"Name\":\"Zinx Heartbeat\",\n  \"Host\":\"127.0.0.1\",\n  \"TcpPort\":8999,\n  \"MaxConn\":3,\n  \"WorkerPoolSize\":10,\n  \"LogIsolati"
  },
  {
    "path": "examples/zinx_heartbeat/server/server.go",
    "chars": 1235,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n\t\"time\"\n)\n\n// User-defined h"
  },
  {
    "path": "examples/zinx_heartbeat/server_default/conf/zinx.json",
    "chars": 156,
    "preview": "{\n  \"Name\":\"Zinx Heartbeat\",\n  \"Host\":\"127.0.0.1\",\n  \"TcpPort\":8999,\n  \"MaxConn\":3,\n  \"WorkerPoolSize\":10,\n  \"LogIsolati"
  },
  {
    "path": "examples/zinx_heartbeat/server_default/server_default.go",
    "chars": 185,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/znet\"\n\t\"time\"\n)\n\nfunc main() {\n\ts := znet.NewServer()\n\n\t// Start heartbea"
  },
  {
    "path": "examples/zinx_interceptor/client/client.go",
    "chars": 317,
    "preview": "package main\n\nimport (\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\nfunc main() {\n\tclient :"
  },
  {
    "path": "examples/zinx_interceptor/interceptors/interceptor_1.go",
    "chars": 515,
    "preview": "package interceptors\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n)\n\n// Custom Interceptor 1\n"
  },
  {
    "path": "examples/zinx_interceptor/router/route.go",
    "chars": 270,
    "preview": "package router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n"
  },
  {
    "path": "examples/zinx_interceptor/server/server.go",
    "chars": 366,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_interceptor/interceptors\"\n\t\"github.com/aceld/zinx/examples/"
  },
  {
    "path": "examples/zinx_kcp/client/kcp_client.go",
    "chars": 1622,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"github.com/xtaci/kcp-go\"\n"
  },
  {
    "path": "examples/zinx_kcp/server/server.go",
    "chars": 1859,
    "preview": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zconf\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github"
  },
  {
    "path": "examples/zinx_logger/client/client.go",
    "chars": 1292,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"g"
  },
  {
    "path": "examples/zinx_logger/server/my_logger.go",
    "chars": 1040,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n)\n\n// User-defined logging method\n// The internal engine logging method of zinx"
  },
  {
    "path": "examples/zinx_logger/server/server.go",
    "chars": 978,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/"
  },
  {
    "path": "examples/zinx_metrics/client/c1/client.go",
    "chars": 1410,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"g"
  },
  {
    "path": "examples/zinx_metrics/client/c2/client.go",
    "chars": 1390,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"g"
  },
  {
    "path": "examples/zinx_metrics/server/conf/zinx.json",
    "chars": 235,
    "preview": "{\n  \"Name\":\"MyZinxServer001\",\n  \"Host\":\"0.0.0.0\",\n  \"TCPPort\":8999,\n  \"MaxConn\":3,\n  \"WorkerPoolSize\":10,\n  \"LogIsolatio"
  },
  {
    "path": "examples/zinx_metrics/server/server.go",
    "chars": 1043,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_server/s_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.c"
  },
  {
    "path": "examples/zinx_mutiport/client8999/client.go",
    "chars": 1410,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"g"
  },
  {
    "path": "examples/zinx_mutiport/client9000/client.go",
    "chars": 1390,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"g"
  },
  {
    "path": "examples/zinx_mutiport/server/server.go",
    "chars": 1562,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_server/s_router\"\n\t\"github.com/aceld/zinx/zconf\"\n\t\"gi"
  },
  {
    "path": "examples/zinx_new_router/client/client.go",
    "chars": 1559,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n// "
  },
  {
    "path": "examples/zinx_new_router/server/conf/zinx.json",
    "chars": 160,
    "preview": "{\n  \"Name\":\"zinx v-0.10 demoApp\",\n  \"Host\":\"127.0.0.1\",\n  \"TCPPort\":7777,\n  \"MaxConn\":3,\n  \"WorkerPoolSize\":10,\n  \"LogDi"
  },
  {
    "path": "examples/zinx_new_router/server/server.go",
    "chars": 1613,
    "preview": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n\t\"time\"\n)\n\ntype Te"
  },
  {
    "path": "examples/zinx_protobuf/client/client.go",
    "chars": 1488,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb\"\n\t\"githu"
  },
  {
    "path": "examples/zinx_protobuf/server/server.go",
    "chars": 970,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb\"\n\t\"gith"
  },
  {
    "path": "examples/zinx_routerSlices/client/client.go",
    "chars": 396,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"net\"\n)\n\nfunc main() {\n\tconn, err := net.Dial(\"tcp\", \"127."
  },
  {
    "path": "examples/zinx_routerSlices/default_func_server/server.go",
    "chars": 399,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\nfunc DefaultTest"
  },
  {
    "path": "examples/zinx_routerSlices/router_func_server/server.go",
    "chars": 2700,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zconf\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zne"
  },
  {
    "path": "examples/zinx_routerSlices/router_group_server/server.go",
    "chars": 2889,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/zconf\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zn"
  },
  {
    "path": "examples/zinx_server/Makefile",
    "chars": 269,
    "preview": "PROJECT_NAME:=zinx_server\nVERSION:=v1\n\n\n\n.PHONY: image run build clean\n\nbuild:\n\tbash build.sh ${PROJECT_NAME}\n\nimage:\n\td"
  },
  {
    "path": "examples/zinx_server/build.sh",
    "chars": 581,
    "preview": "#!/bin/bash\n\nset -e\n\nAPP_NAME=$1\nAPP_VERSION=v$(cat version)\nBUILD_VERSION=$(git log -1 --oneline)\nBUILD_TIME=$(date \"+%"
  },
  {
    "path": "examples/zinx_server/conf/zinx.json",
    "chars": 231,
    "preview": "{\r\n  \"Name\":\"zinx server Demo\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TCPPort\":8999,\r\n  \"MaxConn\":3,\r\n  \"WorkerMode\": \"\",\r\n  \"Worke"
  },
  {
    "path": "examples/zinx_server/dockerfile",
    "chars": 136,
    "preview": "FROM centos:8\nCOPY zinx_server /zinx-server\nCOPY /conf/zinx.json /conf/zinx.json\nWORKDIR /\nEXPOSE  8999\n\nENTRYPOINT [ \"/"
  },
  {
    "path": "examples/zinx_server/main.go",
    "chars": 1489,
    "preview": "/**\n* @Author: Aceld\n* @Date: 2020/12/24 00:24\n* @Mail: danbing.at@gmail.com\n*    zinx server demo\n */\npackage main\n\nimp"
  },
  {
    "path": "examples/zinx_server/s_router/hello.go",
    "chars": 656,
    "preview": "package s_router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)"
  },
  {
    "path": "examples/zinx_server/s_router/ping.go",
    "chars": 629,
    "preview": "package s_router\n\nimport (\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet\"\n)"
  },
  {
    "path": "examples/zinx_server/version",
    "chars": 8,
    "preview": "v 1.0.0\n"
  },
  {
    "path": "examples/zinx_tls/client/client.go",
    "chars": 980,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/aceld/zinx/znet"
  },
  {
    "path": "examples/zinx_tls/server/server.go",
    "chars": 4327,
    "preview": "package main\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/p"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.10Test/client0/Client0.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.10Test/client1/Client1.go",
    "chars": 1339,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.10Test/server/Server.go",
    "chars": 1940,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype P"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.10Test/server/conf/zinx.json",
    "chars": 120,
    "preview": "{\r\n  \"Name\":\"zinx v-0.10 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3,\r\n  \"WorkerPoolSize\":10\r\n}\r\n"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.11Test/client0/Client0.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.11Test/client1/Client1.go",
    "chars": 1339,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.11Test/server/Server.go",
    "chars": 2068,
    "preview": "/**\n* @Author: Aceld\n* @Date: 2019/4/30 17:42\n* @Mail: danbing.at@gmail.com\n*  ZinxV0.11测试,测试Zinx 日志模块功能 zlog模块\n */\npack"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.11Test/server/conf/zinx.json",
    "chars": 169,
    "preview": "{\r\n  \"Name\":\"zinx v-0.10 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3,\r\n  \"WorkerPoolSize\":10,\r\n  "
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.1Test/client/client.go",
    "chars": 629,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Println(\"Client Test ... start\")\n\t//3秒之后"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.1Test/server/server.go",
    "chars": 212,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// Server 模块的测试函数\nfunc main() {\n\n\t/*\n\t\t服务端测试\n\t*/\n\t//1 创建一个server"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.2Test/client/client.go",
    "chars": 629,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Println(\"Client Test ... start\")\n\t//3秒之后"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.2Test/server/server.go",
    "chars": 213,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// Server 模块的测试函数\nfunc main() {\n\n\t/*\n\t\t服务端测试\n\t*/\n\t//1 创建一个server"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.3Test/client/client.go",
    "chars": 632,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Println(\"Client Test ... start\")\n\t//3秒之后"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.3Test/server/server.go",
    "chars": 1172,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype "
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.4Test/client/client.go",
    "chars": 632,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Println(\"Client Test ... start\")\n\t//3秒之后"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.4Test/server/conf/zinx.json",
    "chars": 95,
    "preview": "{\r\n  \"Name\":\"zinx v-0.4 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3\r\n}\r\n"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.4Test/server/server.go",
    "chars": 1140,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype "
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.5Test/client/client.go",
    "chars": 1318,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.5Test/server/conf/zinx.json",
    "chars": 95,
    "preview": "{\r\n  \"Name\":\"zinx v-0.5 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3\r\n}\r\n"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.5Test/server/server.go",
    "chars": 818,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype "
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/client0/Client0.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/client1/Client1.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/server/Server.go",
    "chars": 1111,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype P"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/server/conf/zinx.json",
    "chars": 95,
    "preview": "{\r\n  \"Name\":\"zinx v-0.6 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3\r\n}\r\n"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.8Test/client0/Client0.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.8Test/client1/Client1.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.8Test/server/Server.go",
    "chars": 1111,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype P"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.8Test/server/conf/zinx.json",
    "chars": 119,
    "preview": "{\r\n  \"Name\":\"zinx v-0.8 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3,\r\n  \"WorkerPoolSize\":10\r\n}\r\n"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.9Test/client0/Client0.go",
    "chars": 1319,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.9Test/client1/Client1.go",
    "chars": 1339,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\n/*\n模拟客户端\n*/\nfunc main() {\n\n\tfmt.Pri"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.9Test/server/Server.go",
    "chars": 1532,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/znet\"\n)\n\n// ping test 自定义路由\ntype P"
  },
  {
    "path": "examples/zinx_version_ex/ZinxV0.9Test/server/conf/zinx.json",
    "chars": 119,
    "preview": "{\r\n  \"Name\":\"zinx v-0.8 demoApp\",\r\n  \"Host\":\"127.0.0.1\",\r\n  \"TcpPort\":7777,\r\n  \"MaxConn\":3,\r\n  \"WorkerPoolSize\":10\r\n}\r\n"
  },
  {
    "path": "examples/zinx_version_ex/datapackDemo/client/client.go",
    "chars": 856,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"net\"\n)\n\nfunc main() {\n\t//客户端goroutine,负责模拟粘包的数据,然后进行发送\n\tc"
  },
  {
    "path": "examples/zinx_version_ex/datapackDemo/server/server.go",
    "chars": 1321,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/zpack\"\n\t\"io\"\n\t\"net\"\n)\n\n// 只是负责测试datapack拆包,封包功能\nfunc main() {\n\t//创"
  },
  {
    "path": "examples/zinx_version_ex/protoDemo/main.go",
    "chars": 804,
    "preview": "package main\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_version_ex/protoDemo/pb\"\n\t\"github.co"
  },
  {
    "path": "examples/zinx_version_ex/protoDemo/pb/Person.pb.go",
    "chars": 6013,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: Person.proto\n\npackage pb\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github"
  },
  {
    "path": "examples/zinx_version_ex/protoDemo/pb/Person.proto",
    "chars": 486,
    "preview": "syntax = \"proto3\"; \t\t\t\t\t\t//指定版本信息,不指定会报错\r\npackage pb;\t\t\t\t\t\t//后期生成go文件的包名\r\n\r\n//message为关键字,作用为定义一种消息类型\r\nmessage Person {\r"
  },
  {
    "path": "examples/zinx_websocket/client/client.go",
    "chars": 1639,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/aceld/zinx/examples/zinx_client/c_router\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"g"
  },
  {
    "path": "examples/zinx_websocket/minicode/.eslintrc.js",
    "chars": 587,
    "preview": "/*\n * Eslint config file\n * Documentation: https://eslint.org/docs/user-guide/configuring/\n * Install the Eslint extensi"
  },
  {
    "path": "examples/zinx_websocket/minicode/app.js",
    "chars": 1826,
    "preview": "const Buffer = require(\"buffer\").Buffer;\nApp({\n    onLaunch() {\n        const socket = wx.connectSocket({\n            ur"
  },
  {
    "path": "examples/zinx_websocket/minicode/app.json",
    "chars": 313,
    "preview": "{\n  \"pages\": [\n    \"index/index\"\n  ],\n  \"window\": {\n    \"backgroundTextStyle\": \"light\",\n    \"navigationBarBackgroundColo"
  },
  {
    "path": "examples/zinx_websocket/minicode/app.wxss",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/zinx_websocket/minicode/index/index.js",
    "chars": 259,
    "preview": "const app = getApp()\n\nPage({\n  data: {\n\n  },\n  onLoad() {\n    console.log('代码片段是一种迷你、可分享的小程序或小游戏项目,可用于分享小程序和小游戏的开发经验、展示组"
  },
  {
    "path": "examples/zinx_websocket/minicode/index/index.json",
    "chars": 27,
    "preview": "{\n  \"usingComponents\": {}\n}"
  },
  {
    "path": "examples/zinx_websocket/minicode/index/index.wxml",
    "chars": 53,
    "preview": "<view class=\"intro\">欢迎使用代码片段,可在控制台查看代码片段的说明和文档</view>"
  },
  {
    "path": "examples/zinx_websocket/minicode/index/index.wxss",
    "chars": 48,
    "preview": ".intro {\n  margin: 30px;\n  text-align: center;\n}"
  },
  {
    "path": "examples/zinx_websocket/minicode/package.json",
    "chars": 51,
    "preview": "{\n  \"dependencies\": {\n    \"buffer\": \"^6.0.3\"\n  }\n}\n"
  },
  {
    "path": "examples/zinx_websocket/minicode/project.config.json",
    "chars": 659,
    "preview": "{\n    \"appid\": \"wx0b3c079df9f406b6\",\n    \"compileType\": \"miniprogram\",\n    \"libVersion\": \"2.30.4\",\n    \"packOptions\": {\n"
  },
  {
    "path": "examples/zinx_websocket/minicode/project.private.config.json",
    "chars": 286,
    "preview": "{\n    \"description\": \"项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.co"
  },
  {
    "path": "examples/zinx_websocket/minicode/sitemap.json",
    "chars": 159,
    "preview": "{\n  \"desc\": \"关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html\",\n  \"rules\": [{\n  "
  },
  {
    "path": "examples/zinx_websocket/server/server.go",
    "chars": 407,
    "preview": "package main\n\nimport (\n\t\"github.com/aceld/zinx/examples/zinx_server/s_router\"\n\t\"github.com/aceld/zinx/zconf\"\n\t\"github.co"
  },
  {
    "path": "go.mod",
    "chars": 940,
    "preview": "module github.com/aceld/zinx\n\ngo 1.23.0\n\nrequire (\n\tgithub.com/gorilla/websocket v1.5.0\n\tgithub.com/stretchr/testify v1."
  },
  {
    "path": "go.sum",
    "chars": 11588,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1/go."
  },
  {
    "path": "logo/zinxlogo.go",
    "chars": 1213,
    "preview": "package logo\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/zconf\"\n)\n\nvar zinxLogo = `                                       "
  },
  {
    "path": "zasync_op/async_op.go",
    "chars": 3025,
    "preview": "/*\nPackage zasync_op\n@Author:14March\n@File:async_op.go\n*/\npackage zasync_op\n\nimport (\n\t\"sync\"\n)\n\n/*\n\t<异步IO模块简介>\n\n1.业务线程执"
  },
  {
    "path": "zasync_op/async_op_result.go",
    "chars": 2900,
    "preview": "/*\n\tPackage zasync_op\n\t@Author:14March\n\t@File:async_op_result.go\n*/\n\npackage zasync_op\n\nimport (\n\t\"sync/atomic\"\n\n\t\"githu"
  },
  {
    "path": "zasync_op/async_worker.go",
    "chars": 779,
    "preview": "/*\n\tPackage zasync_op\n\t@Author:14March\n\t@File:async_worker.go\n*/\n\npackage zasync_op\n\nimport \"github.com/aceld/zinx/zlog\""
  },
  {
    "path": "zconf/env.go",
    "chars": 885,
    "preview": "/**\n * User: coder.sdp@gmail.com\n * Date: 2023/9/8\n * Time: 14:18\n */\n\npackage zconf\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n)\n"
  },
  {
    "path": "zconf/userconf.go",
    "chars": 3702,
    "preview": "package zconf\n\nimport \"github.com/aceld/zinx/zlog\"\n\n// UserConfToGlobal, Note that if UserConf is used,\n// the method sh"
  },
  {
    "path": "zconf/zconf.go",
    "chars": 9111,
    "preview": "// @Title  globalobj.go\n// @Description  相关配置文件定义及加载方式\n// defines a configuration structure named \"Config\" along with it"
  },
  {
    "path": "zdecoder/crc.go",
    "chars": 3962,
    "preview": "package zdecoder\n\nvar crc16_h = []byte{\n\t0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,\n\t0x80, 0x41, 0x00, "
  },
  {
    "path": "zdecoder/htlvcrcdecoder.go",
    "chars": 5050,
    "preview": "// HTLV+CRC, H header code, T function code, L data length, V data content\n//+------+-------+-------+--------+--------+\n"
  },
  {
    "path": "zdecoder/ltvdecoder_little.go",
    "chars": 6281,
    "preview": "// LTV, which stands for Length-Tag(Type)-Value, is a simple and practical data transmission scheme.\n// In the definitio"
  },
  {
    "path": "zdecoder/tlvdecoder.go",
    "chars": 6304,
    "preview": "// TLV, which stands for Tag(Type)-Length-Value, is a simple and practical data transmission scheme.\n// In the definitio"
  },
  {
    "path": "ziface/iclient.go",
    "chars": 2290,
    "preview": "// @Title  iclient.go\n// @Description  Provides all interface declarations for the Client abstraction layer.\n// @Author "
  },
  {
    "path": "ziface/iconnection.go",
    "chars": 3112,
    "preview": "// @Title  iconnection.go\n// @Description  Declaration of all connection-related methods\n// @Author  Aceld - Thu Mar 11 "
  },
  {
    "path": "ziface/iconnmanager.go",
    "chars": 1410,
    "preview": "// @Title iconnmanager.go\n// @Description Connection management related operations, including adding, removing, getting "
  },
  {
    "path": "ziface/idatapack.go",
    "chars": 967,
    "preview": "// @Title idatapack.go\n// @Description Message packing and unpacking methods\n// @Author Aceld - Thu Mar 11 10:32:29 CST "
  },
  {
    "path": "ziface/idecoder.go",
    "chars": 89,
    "preview": "package ziface\n\ntype IDecoder interface {\n\tIInterceptor\n\tGetLengthField() *LengthField\n}\n"
  },
  {
    "path": "ziface/iheartbeat.go",
    "chars": 1408,
    "preview": "package ziface\n\ntype IHeartbeatChecker interface {\n\tSetOnRemoteNotAlive(OnRemoteNotAlive)\n\tSetHeartbeatMsgFunc(HeartBeat"
  },
  {
    "path": "ziface/iinterceptor.go",
    "chars": 835,
    "preview": "/**\n * @author uuxia\n * @date 15:54 2023/3/10\n * @description\n **/\n\npackage ziface\n\n// Input data for interceptor\n// (拦截"
  },
  {
    "path": "ziface/ilengthfield.go",
    "chars": 1343,
    "preview": "package ziface\n\nimport \"encoding/binary\"\n\ntype IFrameDecoder interface {\n\tDecode(buff []byte) [][]byte\n}\n\n// ILengthFiel"
  },
  {
    "path": "ziface/ilogger.go",
    "chars": 407,
    "preview": "package ziface\n\nimport \"context\"\n\ntype ILogger interface {\n\t//without context\n\tInfoF(format string, v ...interface{})\n\tE"
  },
  {
    "path": "ziface/imessage.go",
    "chars": 741,
    "preview": "// @Title imessage.go\n// @Description Provides basic methods for messages\n// @Author Aceld - Thu Mar 11 10:32:29 CST 201"
  },
  {
    "path": "ziface/imsghandler.go",
    "chars": 1580,
    "preview": "// @Title imsghandler.go\n// @Description Provides interfaces for worker startup and handling message business calls\n// @"
  },
  {
    "path": "ziface/inotify.go",
    "chars": 907,
    "preview": "package ziface\n\ntype Inotify interface {\n\t// Whether there is a connection with this id\n\t// (是否有这个id)\n\tHasIdConn(id uint"
  },
  {
    "path": "ziface/irequest.go",
    "chars": 2985,
    "preview": "// @Title irequest.go\n// @Description Provides all interface declarations for connection requests\n// @Author Aceld - Thu"
  },
  {
    "path": "ziface/irouter.go",
    "chars": 1752,
    "preview": "// @Title irouter.go\n// @Description Provides all interface declarations for message routing\n// @Author Aceld - Thu Mar "
  },
  {
    "path": "ziface/iserver.go",
    "chars": 2379,
    "preview": "// @Title iserver.go\n// @Description Provides all interface declarations for the Server abstraction layer\n// @Author Ace"
  },
  {
    "path": "ziface/options.go",
    "chars": 266,
    "preview": "package ziface\n\nimport \"time\"\n\ntype MsgSendOptionObj struct {\n\tTimeout time.Duration\n}\n\ntype MsgSendOption func(opt *Msg"
  },
  {
    "path": "zinterceptor/chain.go",
    "chars": 1992,
    "preview": "/**\n * @author uuxia\n * @date 15:56 2023/3/10\n * @description 责任链模式\n **/\npackage zinterceptor\n\nimport \"github.com/aceld/"
  },
  {
    "path": "zinterceptor/framedecoder.go",
    "chars": 23225,
    "preview": "/**\n * @author uuxia\n * @date 15:57 2023/3/10\n * @description 通用解码器\n **/\n\npackage zinterceptor\n\nimport (\n\t\"bytes\"\n\t\"enco"
  },
  {
    "path": "zinterceptor/interceptor.go",
    "chars": 1309,
    "preview": "/**\n * @author uuxia\n * @date 15:58 2023/3/10\n * @description 通过拦截,处理数据,任务向下传递\n **/\n\npackage zinterceptor\n\n// 暂时不用\n\n/*\n/"
  },
  {
    "path": "zinx_app_demo/mmo_game/README-CN.md",
    "chars": 4187,
    "preview": "# Zinx应用-MMO游戏案例\n\n[English](README.md) | 简体中文\n\n\n## 〇. MMO Game Client 案例源代码(仅供学习使用)\n\nhttps://github.com/aceld/mmo_game_c"
  },
  {
    "path": "zinx_app_demo/mmo_game/README.md",
    "chars": 4753,
    "preview": "# Zinx Application - MMO Game Case Study\n\nEnglish | [简体中文](README-CN.md)\n\n## 0. MMO Game Client Source Code\n\nhttps://git"
  },
  {
    "path": "zinx_app_demo/mmo_game/api/move.go",
    "chars": 1254,
    "preview": "package api\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zinx_app_demo/mmo_game/core\"\n\t\"git"
  },
  {
    "path": "zinx_app_demo/mmo_game/api/world_chat.go",
    "chars": 1176,
    "preview": "package api\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zinx_app_demo/mmo_game/core\"\n\t\"git"
  },
  {
    "path": "zinx_app_demo/mmo_game/client_AI_robot.go",
    "chars": 5347,
    "preview": "//go:build robot\n// +build robot\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net\"\n\t\""
  },
  {
    "path": "zinx_app_demo/mmo_game/conf/zinx.json",
    "chars": 171,
    "preview": "{\r\n  \"Name\":\"Zinx Game\",\r\n  \"Host\":\"0.0.0.0\",\r\n  \"TcpPort\":8999,\r\n  \"MaxConn\":3000,\r\n  \"WorkerPoolSize\":10,\r\n  \"LogDir\":"
  },
  {
    "path": "zinx_app_demo/mmo_game/core/aoi.go",
    "chars": 6057,
    "preview": "package core\n\nimport \"fmt\"\n\nconst (\n\tAOI_MIN_X  int = 85\n\tAOI_MAX_X  int = 410\n\tAOI_CNTS_X int = 10\n\tAOI_MIN_Y  int = 75"
  },
  {
    "path": "zinx_app_demo/mmo_game/core/aoi_test.go",
    "chars": 710,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestNewAOIManager(t *testing.T) {\n\taoiMgr := NewAOIManager(100, 300, 4,"
  },
  {
    "path": "zinx_app_demo/mmo_game/core/grid.go",
    "chars": 1501,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\n// GrID A grid class in a map 一个地图中的格子类\ntype GrID struct {\n\tGID       int      "
  },
  {
    "path": "zinx_app_demo/mmo_game/core/player.go",
    "chars": 10530,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zinx"
  },
  {
    "path": "zinx_app_demo/mmo_game/core/world_manager.go",
    "chars": 2577,
    "preview": "package core\n\nimport (\n\t\"sync\"\n)\n\n// WorldManager The overall management module of the current game world 当前游戏世界的总管理模块\nt"
  },
  {
    "path": "zinx_app_demo/mmo_game/pb/build.sh",
    "chars": 38,
    "preview": "#!/bin/bash\nprotoc --go_out=. *.proto\n"
  },
  {
    "path": "zinx_app_demo/mmo_game/pb/msg.pb.go",
    "chars": 12272,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: msg.proto\n\npackage pb\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github.co"
  },
  {
    "path": "zinx_app_demo/mmo_game/pb/msg.proto",
    "chars": 995,
    "preview": "syntax=\"proto3\";                // Version of protobuf\r\npackage pb;                     // Current package name\r\noption "
  },
  {
    "path": "zinx_app_demo/mmo_game/server.go",
    "chars": 2423,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/zdecoder\"\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx"
  },
  {
    "path": "zlog/default.go",
    "chars": 1025,
    "preview": "package zlog\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/aceld/zinx/ziface\"\n)\n\nvar zLogInstance ziface.ILogger = new(zinxD"
  },
  {
    "path": "zlog/logger_core.go",
    "chars": 11177,
    "preview": "// Package zlog provides logging interfaces for zinx.\n// This includes:\n//\n// - stdzlog module, which provides global lo"
  },
  {
    "path": "zlog/stdzlog.go",
    "chars": 2966,
    "preview": "// @Title stdzlog.go\n// @Description Wraps zlogger log methods to provide global methods\n// @Author Aceld - Thu Mar 11 1"
  },
  {
    "path": "zlog/zlog_test.go",
    "chars": 1586,
    "preview": "package zlog_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/aceld/zinx/zlog\"\n)\n\nfunc TestStdZLog(t *testing.T) {\n\n\t//测试 默认debug"
  },
  {
    "path": "znet/acceptdelay.go",
    "chars": 582,
    "preview": "package znet\n\nimport (\n\t\"time\"\n)\n\nconst (\n\tmaxDelay = 1 * time.Second\n)\n\nvar AcceptDelay *acceptDelay\n\nfunc init() {\n\tAc"
  },
  {
    "path": "znet/acceptdelay_test.go",
    "chars": 645,
    "preview": "package znet\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc setup() {\n\tfmt.Pri"
  },
  {
    "path": "znet/callbacks.go",
    "chars": 3748,
    "preview": "package znet\n\n// callbackNode represents a node in the callback linked list\n// Each node contains handler identifier, ke"
  },
  {
    "path": "znet/callbacks_test.go",
    "chars": 3128,
    "preview": "package znet\n\nimport (\n\t\"testing\"\n)\n\nfunc TestCallback(t *testing.T) {\n\t// Test empty list\n\tcb := &callbacks{}\n\tif cb.Le"
  },
  {
    "path": "znet/chainbuilder.go",
    "chars": 1595,
    "preview": "/**\n * @author uuxia\n * @date 15:57 2023/3/10\n * @description 拦截器管理\n **/\n\npackage znet\n\nimport (\n\t\"github.com/aceld/zinx"
  },
  {
    "path": "znet/client.go",
    "chars": 9686,
    "preview": "package znet\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/aceld"
  },
  {
    "path": "znet/connection.go",
    "chars": 15503,
    "preview": "package znet\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"net\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t"
  },
  {
    "path": "znet/connmanager.go",
    "chars": 3223,
    "preview": "package znet\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.com/aceld/zinx/zlog\"\n\t\"github.com/"
  },
  {
    "path": "znet/defaultrouterfunc.go",
    "chars": 2217,
    "preview": "package znet\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"path\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/aceld/zinx/ziface\"\n\t\"github.c"
  }
]

// ... and 33 more files (download for full content)

About this extraction

This page contains the full source code of the aceld/zinx GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 233 files (532.8 KB), approximately 183.8k tokens, and a symbol index with 1240 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!