|
@@ -197,7 +197,7 @@ func (h *Hub) AllConnectedChannelWithStarted() []string {
|
|
|
cs := make([]string, 0)
|
|
cs := make([]string, 0)
|
|
|
h.lines.Range(func(id int, line *Line) bool {
|
|
h.lines.Range(func(id int, line *Line) bool {
|
|
|
if line.state == StateConnected {
|
|
if line.state == StateConnected {
|
|
|
- cs = append(cs, fmt.Sprintf("%s|%d", line.channel, line.updated.UnixMilli()))
|
|
|
|
|
|
|
+ cs = append(cs, fmt.Sprintf("%s|%d", line.channel, line.started.UnixMilli()))
|
|
|
}
|
|
}
|
|
|
return true
|
|
return true
|
|
|
})
|
|
})
|
|
@@ -337,8 +337,8 @@ func (h *Hub) sendRequest(gd *GetData) (count int, err error) {
|
|
|
}
|
|
}
|
|
|
err := h.ConnectToServer(channel, false, nil, false)
|
|
err := h.ConnectToServer(channel, false, nil, false)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Println(err)
|
|
|
|
|
- return 0, err
|
|
|
|
|
|
|
+ time.Sleep(time.Millisecond * 400)
|
|
|
|
|
+ continue
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
time.Sleep(time.Millisecond * 400) // 故意将时间缩小一点
|
|
time.Sleep(time.Millisecond * 400) // 故意将时间缩小一点
|
|
@@ -608,73 +608,60 @@ func (h *Hub) ConnectDuration(line *Line) time.Duration {
|
|
|
|
|
|
|
|
// 绑定端口,建立服务
|
|
// 绑定端口,建立服务
|
|
|
// 需要程序运行时调用
|
|
// 需要程序运行时调用
|
|
|
-func (h *Hub) BindForServer(info *conn.HostInfo) (err error) {
|
|
|
|
|
|
|
+func (h *Hub) BindForServer(host *conn.HostInfo) (err error) {
|
|
|
|
|
+ // 验证并加入到hub里
|
|
|
doConnectFunc := func(conn conn.Connect) {
|
|
doConnectFunc := func(conn conn.Connect) {
|
|
|
- proto, version, channel, auth, err := conn.ReadAuthInfo()
|
|
|
|
|
|
|
+ channel, err := ServerCheckAuthInfo(conn, host, h.channel, h.authFunc, h.checkAuthFunc)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Println("[BindForServer ReadAuthInfo ERROR]", err)
|
|
|
|
|
- conn.Close()
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- if version != info.Version || proto != info.Proto {
|
|
|
|
|
- log.Println("wrong version or protocol: ", version, proto)
|
|
|
|
|
- conn.Close()
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- if !h.checkAuthFunc(nil, proto, version, channel, auth) {
|
|
|
|
|
- err = fmt.Errorf("[server checkAuthFunc ERROR] in proto: %s, version: %d, channel: %s, auth: %s", proto, version, channel, string(auth))
|
|
|
|
|
- log.Println(err)
|
|
|
|
|
- conn.Close()
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- // 发送频道信息
|
|
|
|
|
- if err := conn.WriteAuthInfo(h.channel, h.authFunc(nil, proto, version, channel, auth)); err != nil {
|
|
|
|
|
- log.Println("[WriteAuthInfo ERROR]", err)
|
|
|
|
|
|
|
+ log.Println("[BindForServer ServerCheckAuthInfo] error:", err)
|
|
|
conn.Close()
|
|
conn.Close()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
// 将连接加入现有连接中
|
|
// 将连接加入现有连接中
|
|
|
- done := false
|
|
|
|
|
- h.lines.Range(func(id int, line *Line) bool {
|
|
|
|
|
- if line.state == StateDisconnected && line.host == nil && line.IsChannelEqual(channel) {
|
|
|
|
|
- line.Start(channel, conn, nil)
|
|
|
|
|
- done = true
|
|
|
|
|
|
|
+ var line *Line
|
|
|
|
|
+ h.lines.Range(func(id int, ln *Line) bool {
|
|
|
|
|
+ if ln.state == StateDisconnected && ln.host == nil && ln.IsChannelEqual(channel) {
|
|
|
|
|
+ line = ln
|
|
|
|
|
+ ln.proxyChannel = ""
|
|
|
|
|
+ ln.Start(channel, conn, nil)
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
return true
|
|
return true
|
|
|
})
|
|
})
|
|
|
// 新建一个连接
|
|
// 新建一个连接
|
|
|
- if !done {
|
|
|
|
|
- line := NewConnect(h.cf, h, channel, conn, nil, false)
|
|
|
|
|
|
|
+ if line == nil {
|
|
|
|
|
+ line = NewConnect(h.cf, h, channel, "", conn, nil, false)
|
|
|
h.addLine(line)
|
|
h.addLine(line)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if info.Version == ws2.VERSION && info.Proto == ws2.PROTO {
|
|
|
|
|
|
|
+ // 通过不同的协议标识执行不同的库
|
|
|
|
|
+ if host.Version == ws2.VERSION && host.Proto == ws2.PROTO {
|
|
|
bind := ""
|
|
bind := ""
|
|
|
- if info.Bind != "" {
|
|
|
|
|
- bind = net.JoinHostPort(info.Bind, strconv.Itoa(int(info.Port)))
|
|
|
|
|
|
|
+ if host.Bind != "" {
|
|
|
|
|
+ bind = net.JoinHostPort(host.Bind, strconv.Itoa(int(host.Port)))
|
|
|
}
|
|
}
|
|
|
- return ws2.Server(h.cf, bind, info.Path, info.Hash, doConnectFunc)
|
|
|
|
|
- } else if info.Version == tcp2.VERSION && info.Proto == tcp2.PROTO {
|
|
|
|
|
- return tcp2.Server(h.cf, net.JoinHostPort(info.Bind, strconv.Itoa(int(info.Port))), info.Hash, doConnectFunc)
|
|
|
|
|
|
|
+ return ws2.Server(h.cf, bind, host.Path, host.Hash, doConnectFunc)
|
|
|
|
|
+ } else if host.Version == tcp2.VERSION && host.Proto == tcp2.PROTO {
|
|
|
|
|
+ return tcp2.Server(h.cf, net.JoinHostPort(host.Bind, strconv.Itoa(int(host.Port))), host.Hash, doConnectFunc)
|
|
|
}
|
|
}
|
|
|
return errors.New("not connect protocol and version found")
|
|
return errors.New("not connect protocol and version found")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 代理连接,在已经连接的基础上进行代理连接
|
|
// 代理连接,在已经连接的基础上进行代理连接
|
|
|
-func (h *Hub) ProxyConnect(connect conn.Connect, remoteChannel string) (err error) {
|
|
|
|
|
|
|
+func (h *Hub) ClientProxyConnect(line *Line, remoteChannel string) (err error) {
|
|
|
|
|
+ // 获取主机地址
|
|
|
host, err := h.connectHostFunc(remoteChannel, HostTypeDirect)
|
|
host, err := h.connectHostFunc(remoteChannel, HostTypeDirect)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
// 发送代理连接
|
|
// 发送代理连接
|
|
|
buf := conn.ProxyConnectPackageEncode(host.Url())
|
|
buf := conn.ProxyConnectPackageEncode(host.Url())
|
|
|
- if err := connect.WriteRawPackage(buf, true); err != nil {
|
|
|
|
|
|
|
+ if err := line.conn.WriteRawPackage(buf, true); err != nil {
|
|
|
log.Println("[ConnectToServer] WriteRawPackage error:", err)
|
|
log.Println("[ConnectToServer] WriteRawPackage error:", err)
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
// 读取代理结果
|
|
// 读取代理结果
|
|
|
- msgType, _, _, _, data, err := connect.ReadMessage(h.cf.LongReadWait)
|
|
|
|
|
|
|
+ msgType, _, _, _, data, err := line.conn.ReadMessage(h.cf.LongReadWait)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
log.Println("[ConnectToServer] ReadRawPackage error:", err)
|
|
log.Println("[ConnectToServer] ReadRawPackage error:", err)
|
|
|
return err
|
|
return err
|
|
@@ -687,7 +674,7 @@ func (h *Hub) ProxyConnect(connect conn.Connect, remoteChannel string) (err erro
|
|
|
return errors.New(string(data))
|
|
return errors.New(string(data))
|
|
|
}
|
|
}
|
|
|
// 进行auth验证
|
|
// 进行auth验证
|
|
|
- needProxy, err := ClientCheckAuthInfo(connect, host, h.channel, remoteChannel, h.authFunc, h.checkAuthFunc)
|
|
|
|
|
|
|
+ proxyChannel, err := ClientCheckAuthInfo(line.conn, host, h.channel, remoteChannel, h.authFunc, h.checkAuthFunc)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
host.Errors++
|
|
host.Errors++
|
|
|
host.Updated = time.Now()
|
|
host.Updated = time.Now()
|
|
@@ -696,8 +683,8 @@ func (h *Hub) ProxyConnect(connect conn.Connect, remoteChannel string) (err erro
|
|
|
host.Errors = 0
|
|
host.Errors = 0
|
|
|
host.Updated = time.Now()
|
|
host.Updated = time.Now()
|
|
|
}
|
|
}
|
|
|
- if needProxy {
|
|
|
|
|
- return errors.New("proxy with proxy")
|
|
|
|
|
|
|
+ if proxyChannel != "" {
|
|
|
|
|
+ return errors.New("proxy with proxy error with channel: " + proxyChannel)
|
|
|
}
|
|
}
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
@@ -711,7 +698,6 @@ func (h *Hub) ConnectToServer(remoteChannel string, force bool, host *conn.HostI
|
|
|
if !force {
|
|
if !force {
|
|
|
line := h.ChannelToLine(remoteChannel)
|
|
line := h.ChannelToLine(remoteChannel)
|
|
|
if line != nil && line.state == StateConnected {
|
|
if line != nil && line.state == StateConnected {
|
|
|
- // err = fmt.Errorf("[ConnectToServer ERROR] existed channel: %s", channel)
|
|
|
|
|
log.Println("[ConnectToServer] channel existed:", remoteChannel)
|
|
log.Println("[ConnectToServer] channel existed:", remoteChannel)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -737,7 +723,7 @@ func (h *Hub) ConnectToServer(remoteChannel string, force bool, host *conn.HostI
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- needProxy, err := ClientCheckAuthInfo(connect, host, h.channel, remoteChannel, h.authFunc, h.checkAuthFunc)
|
|
|
|
|
|
|
+ proxyChannel, err := ClientCheckAuthInfo(connect, host, h.channel, remoteChannel, h.authFunc, h.checkAuthFunc)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
connect.Close()
|
|
connect.Close()
|
|
|
host.Errors++
|
|
host.Errors++
|
|
@@ -748,31 +734,22 @@ func (h *Hub) ConnectToServer(remoteChannel string, force bool, host *conn.HostI
|
|
|
host.Updated = time.Now()
|
|
host.Updated = time.Now()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 判断是否是代理节点,如果是代理节点还需要进行下一步的连接
|
|
|
|
|
- if needProxy {
|
|
|
|
|
- err := h.ProxyConnect(connect, remoteChannel)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- connect.Close()
|
|
|
|
|
- log.Println("[ProxyConnect] error:", err)
|
|
|
|
|
- return err
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// 将连接加入现有连接中
|
|
// 将连接加入现有连接中
|
|
|
- done := false
|
|
|
|
|
- h.lines.Range(func(id int, line *Line) bool {
|
|
|
|
|
- if line.channel == remoteChannel {
|
|
|
|
|
- if line.state == StateConnected {
|
|
|
|
|
|
|
+ var line *Line
|
|
|
|
|
+ h.lines.Range(func(id int, ln *Line) bool {
|
|
|
|
|
+ if ln.channel == remoteChannel {
|
|
|
|
|
+ if ln.state == StateConnected {
|
|
|
if force {
|
|
if force {
|
|
|
- line.Close(true)
|
|
|
|
|
|
|
+ ln.Close(true)
|
|
|
} else {
|
|
} else {
|
|
|
err = fmt.Errorf("[connectToServer] channel already connected: %s", remoteChannel)
|
|
err = fmt.Errorf("[connectToServer] channel already connected: %s", remoteChannel)
|
|
|
log.Println(err)
|
|
log.Println(err)
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ line = ln
|
|
|
|
|
+ line.proxyChannel = proxyChannel
|
|
|
line.Start(remoteChannel, connect, host)
|
|
line.Start(remoteChannel, connect, host)
|
|
|
- done = true
|
|
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
return true
|
|
return true
|
|
@@ -781,8 +758,8 @@ func (h *Hub) ConnectToServer(remoteChannel string, force bool, host *conn.HostI
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
// 新建一个连接
|
|
// 新建一个连接
|
|
|
- if !done {
|
|
|
|
|
- line := NewConnect(h.cf, h, remoteChannel, connect, host, autoReconnect)
|
|
|
|
|
|
|
+ if line == nil {
|
|
|
|
|
+ line = NewConnect(h.cf, h, remoteChannel, proxyChannel, connect, host, autoReconnect)
|
|
|
h.addLine(line)
|
|
h.addLine(line)
|
|
|
}
|
|
}
|
|
|
return nil
|
|
return nil
|
|
@@ -846,7 +823,7 @@ func (h *Hub) checkConnect() {
|
|
|
case <-proxyTicker.C:
|
|
case <-proxyTicker.C:
|
|
|
now := time.Now().UnixMilli()
|
|
now := time.Now().UnixMilli()
|
|
|
h.lines.Range(func(id int, line *Line) bool {
|
|
h.lines.Range(func(id int, line *Line) bool {
|
|
|
- if line.host != nil && line.host.Proxy && now-line.updated.UnixMilli() > int64(h.cf.ProxyTimeout) {
|
|
|
|
|
|
|
+ if line.host != nil && now-line.lastRead.UnixMilli() > int64(h.cf.ProxyTimeout) {
|
|
|
host, err := h.connectHostFunc(line.channel, HostTypeDirect)
|
|
host, err := h.connectHostFunc(line.channel, HostTypeDirect)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
log.Println("[proxyTicker connectHostFunc]", err)
|
|
log.Println("[proxyTicker connectHostFunc]", err)
|