mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-07 01:32:57 +08:00
修订代码,注释,文档
This commit is contained in:
1
Makefile
1
Makefile
@@ -7,6 +7,7 @@
|
|||||||
#
|
#
|
||||||
# for embedding geoip file:
|
# for embedding geoip file:
|
||||||
# make tags="embed_geoip" macm1
|
# make tags="embed_geoip" macm1
|
||||||
|
#
|
||||||
# 目前发布版直接使用go1.18编译,你如果想编译出相同文件,也要使用go1.18才行
|
# 目前发布版直接使用go1.18编译,你如果想编译出相同文件,也要使用go1.18才行
|
||||||
|
|
||||||
BUILD_VERSION := v1.0.7
|
BUILD_VERSION := v1.0.7
|
||||||
|
32
main.go
32
main.go
@@ -31,6 +31,7 @@ const (
|
|||||||
standardMode
|
standardMode
|
||||||
v2rayCompatibleMode
|
v2rayCompatibleMode
|
||||||
)
|
)
|
||||||
|
const tlslazy_willuseSystemCall = runtime.GOOS == "linux" || runtime.GOOS == "darwin"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configFileName string
|
configFileName string
|
||||||
@@ -216,12 +217,12 @@ func main() {
|
|||||||
|
|
||||||
func listenSer(listener net.Listener, inServer proxy.Server) {
|
func listenSer(listener net.Listener, inServer proxy.Server) {
|
||||||
|
|
||||||
theFunc := func(conn net.Conn) {
|
handleFunc := func(conn net.Conn) {
|
||||||
handleNewIncomeConnection(inServer, conn)
|
handleNewIncomeConnection(inServer, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
network := inServer.Network()
|
network := inServer.Network()
|
||||||
err := netLayer.ListenAndAccept(network, inServer.AddrStr(), theFunc)
|
err := netLayer.ListenAndAccept(network, inServer.AddrStr(), handleFunc)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if utils.CanLogInfo() {
|
if utils.CanLogInfo() {
|
||||||
@@ -700,16 +701,8 @@ afterLocalServerHandshake:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if utils.CanLogDebug() {
|
if utils.CanLogDebug() {
|
||||||
/*
|
|
||||||
go func() {
|
|
||||||
n, e := io.Copy(wrc, wlc)
|
|
||||||
log.Println("本地->远程 转发结束", realTargetAddr.String(), n, e)
|
|
||||||
}()
|
|
||||||
n, e := io.Copy(wlc, wrc)
|
|
||||||
|
|
||||||
log.Println("远程->本地 转发结束", realTargetAddr.String(), n, e)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
if netLayer.UseReadv {
|
||||||
go func() {
|
go func() {
|
||||||
n, e := netLayer.TryCopy(wrc, wlc)
|
n, e := netLayer.TryCopy(wrc, wlc)
|
||||||
log.Println("本地->远程 转发结束", realTargetAddr.String(), n, e)
|
log.Println("本地->远程 转发结束", realTargetAddr.String(), n, e)
|
||||||
@@ -719,16 +712,23 @@ afterLocalServerHandshake:
|
|||||||
log.Println("远程->本地 转发结束", realTargetAddr.String(), n, e)
|
log.Println("远程->本地 转发结束", realTargetAddr.String(), n, e)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//如果两个都是 *net.TCPConn或uds, 则Copy会自动进行splice/sendfile,无需额外处理
|
|
||||||
//go io.Copy(wrc, wlc)
|
go func() {
|
||||||
//io.Copy(wlc, wrc)
|
n, e := io.Copy(wrc, wlc)
|
||||||
|
log.Println("本地->远程 转发结束", realTargetAddr.String(), n, e)
|
||||||
|
}()
|
||||||
|
n, e := io.Copy(wlc, wrc)
|
||||||
|
|
||||||
|
log.Println("远程->本地 转发结束", realTargetAddr.String(), n, e)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
netLayer.Relay(wlc, wrc)
|
netLayer.Relay(wlc, wrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tlslazy_willuseSystemCall = runtime.GOOS == "linux" || runtime.GOOS == "darwin"
|
|
||||||
|
|
||||||
// tryRawCopy 尝试能否直接对拷,对拷 直接使用 原始 TCPConn,也就是裸奔转发
|
// tryRawCopy 尝试能否直接对拷,对拷 直接使用 原始 TCPConn,也就是裸奔转发
|
||||||
// 如果在linux上,则和 xtls的splice 含义相同. 在其他系统时,与xtls-direct含义相同。
|
// 如果在linux上,则和 xtls的splice 含义相同. 在其他系统时,与xtls-direct含义相同。
|
||||||
// 我们内部先 使用 DetectConn进行过滤分析,然后再判断进化为splice 或者退化为普通拷贝
|
// 我们内部先 使用 DetectConn进行过滤分析,然后再判断进化为splice 或者退化为普通拷贝
|
||||||
|
@@ -28,22 +28,26 @@ type Addr struct {
|
|||||||
Network string
|
Network string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RandPortStr() string {
|
||||||
|
return strconv.Itoa(rand.Intn(60000) + 4096)
|
||||||
|
}
|
||||||
|
|
||||||
func GetRandLocalAddr() string {
|
func GetRandLocalAddr() string {
|
||||||
return "0.0.0.0:" + strconv.Itoa(rand.Intn(60000)+4096)
|
return "0.0.0.0:" + RandPortStr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAddrFromUDPAddr(addr *net.UDPAddr) *Addr {
|
func NewAddrFromUDPAddr(addr *net.UDPAddr) *Addr {
|
||||||
return &Addr{
|
return &Addr{
|
||||||
IP: addr.IP,
|
IP: addr.IP,
|
||||||
Port: addr.Port,
|
Port: addr.Port,
|
||||||
//IsUDP: true,
|
|
||||||
Network: "udp",
|
Network: "udp",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//addrStr格式一般为 host:port 的格式;如果不含冒号,将直接认为该字符串是域名或文件名
|
||||||
func NewAddr(addrStr string) (*Addr, error) {
|
func NewAddr(addrStr string) (*Addr, error) {
|
||||||
if !strings.Contains(addrStr, ":") {
|
if !strings.Contains(addrStr, ":") {
|
||||||
//如果 是unix domain socket
|
//unix domain socket, 或者域名默认端口的情况
|
||||||
return &Addr{Name: addrStr}, nil
|
return &Addr{Name: addrStr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ func GetRawConn(reader io.Reader) syscall.RawConn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 用于读端实现了 readv但是写端的情况,比如 从socks5读取 数据, 等裸协议的情况
|
// 用于读端实现了 readv但是写端的情况,比如 从socks5读取 数据, 等裸协议的情况
|
||||||
// 小贴士:将该 net.Buffers 写入io.Writer的话,只需使用 其WriteTo方法。
|
// 小贴士:将该 net.Buffers 写入io.Writer的话,只需使用 其WriteTo方法, 即可自动适配writev。
|
||||||
/*
|
/*
|
||||||
使用方式
|
使用方式
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ func init() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//这里认为能 splice 或 sendfile的 都算
|
//这里认为能 splice 或 sendfile的 都算,具体可参考go标准代码的实现, 总之就是tcp和uds可以
|
||||||
func CanSplice(r interface{}) bool {
|
func CanSplice(r interface{}) bool {
|
||||||
|
|
||||||
if _, ok := r.(*net.TCPConn); ok {
|
if _, ok := r.(*net.TCPConn); ok {
|
||||||
@@ -90,7 +90,7 @@ copy:
|
|||||||
return io.Copy(writeConn, readConn)
|
return io.Copy(writeConn, readConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 类似TryCopy,但是只会读写一次
|
// 类似TryCopy,但是只会读写一次; 因为只读写一次,所以没办法splice
|
||||||
func TryCopyOnce(writeConn io.Writer, readConn io.Reader) (allnum int64, err error) {
|
func TryCopyOnce(writeConn io.Writer, readConn io.Reader) (allnum int64, err error) {
|
||||||
var mr utils.MultiReader
|
var mr utils.MultiReader
|
||||||
var buffers net.Buffers
|
var buffers net.Buffers
|
||||||
@@ -100,12 +100,6 @@ func TryCopyOnce(writeConn io.Writer, readConn io.Reader) (allnum int64, err err
|
|||||||
log.Println("TryCopy", reflect.TypeOf(readConn), "->", reflect.TypeOf(writeConn))
|
log.Println("TryCopy", reflect.TypeOf(readConn), "->", reflect.TypeOf(writeConn))
|
||||||
}
|
}
|
||||||
|
|
||||||
if SystemCanSplice && CanSplice(readConn) && CanSplice(writeConn) {
|
|
||||||
if utils.CanLogDebug() {
|
|
||||||
log.Println("copying with splice")
|
|
||||||
}
|
|
||||||
goto copy
|
|
||||||
}
|
|
||||||
// 不全 支持splice的话,我们就考虑 read端 可 readv 的情况
|
// 不全 支持splice的话,我们就考虑 read端 可 readv 的情况
|
||||||
// 连readv都不让 那就直接 经典拷贝
|
// 连readv都不让 那就直接 经典拷贝
|
||||||
if !UseReadv {
|
if !UseReadv {
|
||||||
@@ -136,16 +130,22 @@ classic:
|
|||||||
if utils.CanLogDebug() {
|
if utils.CanLogDebug() {
|
||||||
log.Println("copying with classic method")
|
log.Println("copying with classic method")
|
||||||
}
|
}
|
||||||
copy:
|
|
||||||
|
|
||||||
//Copy内部实现 会自动进行splice, 若无splice实现则直接使用原始方法 “循环读取 并 写入”
|
bs := utils.GetPacket()
|
||||||
return io.Copy(writeConn, readConn)
|
n, e := readConn.Read(bs)
|
||||||
|
if e != nil {
|
||||||
|
return 0, e
|
||||||
|
}
|
||||||
|
n, e = writeConn.Write(bs[:n])
|
||||||
|
utils.PutPacket(bs)
|
||||||
|
return int64(n), e
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从conn1读取 写入到 conn2,并同时从 conn2读取写入conn1
|
// 从conn1读取 写入到 conn2,并同时从 conn2读取写入conn1
|
||||||
// 阻塞
|
// 阻塞
|
||||||
// 返回从 conn1读取 写入到 conn2的数据
|
// 返回从 conn1读取 写入到 conn2的数据
|
||||||
// UseReadv==true 时 内部使用 TryCopy 进行拷贝
|
// UseReadv==true 时 内部使用 TryCopy 进行拷贝
|
||||||
|
// 会自动优选 splice,readv,不行则使用经典拷贝
|
||||||
func Relay(conn1, conn2 io.ReadWriter) (int64, error) {
|
func Relay(conn1, conn2 io.ReadWriter) (int64, error) {
|
||||||
|
|
||||||
if UseReadv {
|
if UseReadv {
|
||||||
@@ -157,31 +157,3 @@ func Relay(conn1, conn2 io.ReadWriter) (int64, error) {
|
|||||||
return io.Copy(conn2, conn1)
|
return io.Copy(conn2, conn1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 阻塞.
|
|
||||||
func RelayUDP(putter UDP_Putter, extractor UDP_Extractor) {
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
raddr, bs, err := extractor.GetNewUDPRequest()
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
err = putter.WriteUDPRequest(raddr, bs)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
raddr, bs, err := putter.GetNewUDPResponse()
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
err = extractor.WriteUDPResponse(raddr, bs)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -11,6 +11,35 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//本文件内含 一些 转发 udp 数据的 接口与方法
|
//本文件内含 一些 转发 udp 数据的 接口与方法
|
||||||
|
|
||||||
|
// 阻塞.
|
||||||
|
func RelayUDP(putter UDP_Putter, extractor UDP_Extractor) {
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
raddr, bs, err := extractor.GetNewUDPRequest()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
err = putter.WriteUDPRequest(raddr, bs)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
raddr, bs, err := putter.GetNewUDPResponse()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
err = extractor.WriteUDPResponse(raddr, bs)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////// 接口 ////////////////////
|
//////////////////// 接口 ////////////////////
|
||||||
|
|
||||||
type UDPRequestReader interface {
|
type UDPRequestReader interface {
|
||||||
|
@@ -37,7 +37,7 @@ type UserConn struct {
|
|||||||
remainFirstBufLen int //记录读取握手包头时读到的buf的长度. 如果我们读超过了这个部分的话,实际上我们就可以不再使用 optionalReader 读取, 而是直接从Conn读取
|
remainFirstBufLen int //记录读取握手包头时读到的buf的长度. 如果我们读超过了这个部分的话,实际上我们就可以不再使用 optionalReader 读取, 而是直接从Conn读取
|
||||||
|
|
||||||
uuid [16]byte
|
uuid [16]byte
|
||||||
convertedStr string
|
convertedUUIDStr string
|
||||||
version int
|
version int
|
||||||
isUDP bool
|
isUDP bool
|
||||||
isServerEnd bool //for v0
|
isServerEnd bool //for v0
|
||||||
@@ -55,11 +55,11 @@ func (uc *UserConn) GetProtocolVersion() int {
|
|||||||
return uc.version
|
return uc.version
|
||||||
}
|
}
|
||||||
func (uc *UserConn) GetIdentityStr() string {
|
func (uc *UserConn) GetIdentityStr() string {
|
||||||
if uc.convertedStr == "" {
|
if uc.convertedUUIDStr == "" {
|
||||||
uc.convertedStr = proxy.UUIDToStr(uc.uuid)
|
uc.convertedUUIDStr = proxy.UUIDToStr(uc.uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
return uc.convertedStr
|
return uc.convertedUUIDStr
|
||||||
}
|
}
|
||||||
|
|
||||||
//如果是udp,则是多线程不安全的,如果是tcp,则安不安全看底层的链接。
|
//如果是udp,则是多线程不安全的,如果是tcp,则安不安全看底层的链接。
|
||||||
|
@@ -15,11 +15,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestVLess0(t *testing.T) {
|
func TestVLess0(t *testing.T) {
|
||||||
testVLess(0, "9527", t)
|
testVLess(0, netLayer.RandPortStr(), t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVLess1(t *testing.T) {
|
func TestVLess1(t *testing.T) {
|
||||||
testVLess(1, "9538", t)
|
testVLess(1, netLayer.RandPortStr(), t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVLess(version int, port string, t *testing.T) {
|
func testVLess(version int, port string, t *testing.T) {
|
||||||
@@ -115,7 +115,7 @@ func testVLess(version int, port string, t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestVLess0_udp(t *testing.T) {
|
func TestVLess0_udp(t *testing.T) {
|
||||||
testVLessUDP(0, "9638", t)
|
testVLessUDP(0, netLayer.RandPortStr(), t)
|
||||||
}
|
}
|
||||||
|
|
||||||
//func TestVLess1_udp(t *testing.T) {
|
//func TestVLess1_udp(t *testing.T) {
|
||||||
|
@@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestVlesss(t *testing.T) {
|
func TestVlesss(t *testing.T) {
|
||||||
testTls("vlesss", "9507", t)
|
testTls("vlesss", netLayer.RandPortStr(), t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTls(protocol string, port string, t *testing.T) {
|
func testTls(protocol string, port string, t *testing.T) {
|
||||||
|
@@ -46,10 +46,12 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//从Pool中获取一个 *bytes.Buffer
|
||||||
func GetBuf() *bytes.Buffer {
|
func GetBuf() *bytes.Buffer {
|
||||||
return bufPool.Get().(*bytes.Buffer)
|
return bufPool.Get().(*bytes.Buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//将 buf 放回 Pool
|
||||||
func PutBuf(buf *bytes.Buffer) {
|
func PutBuf(buf *bytes.Buffer) {
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
bufPool.Put(buf)
|
bufPool.Put(buf)
|
||||||
@@ -73,12 +75,12 @@ func PutPacket(bs []byte) {
|
|||||||
standardPacketPool.Put(bs[:c])
|
standardPacketPool.Put(bs[:c])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从Pool中获取一个 StandardBytesLength 长度的 []byte
|
||||||
func GetMTU() []byte {
|
func GetMTU() []byte {
|
||||||
return standardBytesPool.Get().([]byte)[:StandardBytesLength]
|
return standardBytesPool.Get().([]byte)[:StandardBytesLength]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从pool中获取 []byte, 在 size <= StandardBytesLength 时有最佳性能
|
// 从pool中获取 []byte, 根据给出长度不同,来源于的Pool会不同.
|
||||||
// 否则会直接调用 GetPacket
|
|
||||||
func GetBytes(size int) []byte {
|
func GetBytes(size int) []byte {
|
||||||
if size <= StandardBytesLength {
|
if size <= StandardBytesLength {
|
||||||
bs := standardBytesPool.Get().([]byte)
|
bs := standardBytesPool.Get().([]byte)
|
||||||
@@ -89,7 +91,7 @@ func GetBytes(size int) []byte {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据bs长度 选择放入各种pool中, 只有cap>=1500 才会被处理
|
// 根据bs长度 选择放入各种pool中, 只有 cap(bs)>=1500 才会被处理
|
||||||
func PutBytes(bs []byte) {
|
func PutBytes(bs []byte) {
|
||||||
c := cap(bs)
|
c := cap(bs)
|
||||||
if c < StandardBytesLength {
|
if c < StandardBytesLength {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// Package utils provides utils that needed by all packages of verysimle
|
// Package utils provides utils that needed by all sub-packages in verysimle
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
//具体实现见 readv_*.go
|
//具体实现见 readv_*.go; 用 GetReadVReader() 函数来获取本平台的对应实现。
|
||||||
type MultiReader interface {
|
type MultiReader interface {
|
||||||
Init([][]byte)
|
Init([][]byte)
|
||||||
Read(fd uintptr) int32
|
Read(fd uintptr) int32
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
# vless v1
|
# vless v1
|
||||||
|
|
||||||
|
目前v1仍然处于研发当中。建议先用v0,等v1完全出炉了再说,本文只是理论探索,实际代码暂未完整实现所有的设计.
|
||||||
|
## 握手协议格式
|
||||||
|
|
||||||
具体我的探讨还可以查看 https://github.com/v2fly/v2ray-core/discussions/1655
|
具体我的探讨还可以查看 https://github.com/v2fly/v2ray-core/discussions/1655
|
||||||
|
|
||||||
总的来说 vless v1 简化了一些流程, 约定永远使用tls(与trojan相同),并重点考虑 非多路复用的 udp over tcp的 fullcone实现。
|
总的来说 vless v1 简化了一些流程, 约定永远使用tls(与trojan相同),并重点考虑 非多路复用的 udp over tcp的 fullcone实现。
|
||||||
|
@@ -54,7 +54,7 @@ func (c *Conn) Read(p []byte) (int, error) {
|
|||||||
return n, e
|
return n, e
|
||||||
}
|
}
|
||||||
c.remainLenForLastFrame -= int64(n)
|
c.remainLenForLastFrame -= int64(n)
|
||||||
// 这里之所以可以放心 减去 n,不怕减成负的,是因为 r的代码里 在读取一帧的数据时,用到了 io.LimitedReader, 一帧的读取长度的上限已被限定,直到 该帧完全被读完为止
|
// 这里之所以可以放心 减去 n,不怕减成负的,是因为 wsutil.Reader 的代码里 在读取一帧的数据时,用到了 io.LimitedReader, 一帧的读取长度的上限已被限定,直到 该帧完全被读完为止
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,16 +1,19 @@
|
|||||||
package ws
|
package ws_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hahahrfool/v2ray_simple/netLayer"
|
||||||
|
"github.com/hahahrfool/v2ray_simple/ws"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ws基本读写功能测试.
|
// ws基本读写功能测试.
|
||||||
// 分别测试写入短数据和长数据
|
// 分别测试写入短数据和长数据
|
||||||
func TestWs(t *testing.T) {
|
func TestWs(t *testing.T) {
|
||||||
listenAddr := "127.0.0.1:7777"
|
listenAddr := netLayer.GetRandLocalAddr()
|
||||||
listener, err := net.Listen("tcp", listenAddr)
|
listener, err := net.Listen("tcp", listenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
@@ -35,7 +38,7 @@ func TestWs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s := NewServer(wsPath)
|
s := ws.NewServer(wsPath)
|
||||||
|
|
||||||
wsConn, err := s.Handshake(conn)
|
wsConn, err := s.Handshake(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -64,7 +67,7 @@ func TestWs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
cli, err := NewClient(listenAddr, wsPath)
|
cli, err := ws.NewClient(listenAddr, wsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
Reference in New Issue
Block a user