Comments (14)
How do you send your pack?
Tcpx requires client send well blocked message. It helps define a stream's length, messageID, header,etc. If you send a random []byte, server will be unaware of decoding it.
Every message should be put into tcpx.Message's Body.
Suggest:
// Normal, If you want to send
/*
map[string]interface{}{
"username":"tcpx",
}
*/
buf,e:=tcpx.PackWithMarshaller(tcpx.Message{
MessageID: 1,
Header: map[string]interface{}{
"auth": "abc",
},
Body: map[string]interface{}{
"username":"tcpx",
},
}, tcpx.JsonMarshaller{})
// If already marshalled, want to send []byte(`hello`)
bf,_ := []byte('hello')
buf,e:=tcpx.PackWithMarshallerAndBody(Message{
MessageID: 1,
Header: map[string]interface{}{
"auth": "abc",
},
}, bf)
from tcpx.
i made a new marshal type to send []byte and receive []byte directly:
type ByteMarshaller struct{}
func (om ByteMarshaller) Marshal(v interface{}) ([]byte, error) {
//return v.([]byte), nil
return reflect.ValueOf(v).Bytes(), nil
}
func (om ByteMarshaller) Unmarshal(data []byte, dest interface{}) error {
rv := reflect.ValueOf(dest)
rv.Elem().Set(reflect.ValueOf(data))
return nil
}
func (om ByteMarshaller) MarshalName() string{
return "ByteMarshaller"
usage:
message which has different length
mes := []byte(message)
Buf, err := tcpx.PackWithMarshaller(tcpx.Message{
MessageID: 22,
Header: nil,
Body: mes ,
}, tcpx.ByteMarshaller{})
_, err = conn.Write(Buf)
or use your code above
message which has different length
mes := []byte(message)
Buf,e := tcpx.PackWithMarshallerAndBody(tcpx.Message{
MessageID: 22,
Header: nil,
}, mes )
_, err = conn.Write(Buf)
both tcpx.ByteMarshaller{} and PackWithMarshallerAndBody() have the same problem, server failed to decode data: "can't read 784 length content block from reader, but read 196"
// server code
var packx = tcpx.NewPackx(tcpx.ByteMarshaller{})
func OnMessage(c *tcpx.Context) {
var messageFromClient []byte
var messageInfo tcpx.Message
messageInfo, e := c.Bind(&messageFromClient)
if e != nil {
panic(e)
}
switch messageInfo.MessageID {
case 22:
bodydata := reflect.ValueOf(messageInfo.Body).Bytes()
// handle(bodydata)
default:
fmt.Println("unexpected message:", messageInfo.MessageID)
}
}
from tcpx.
https://github.com/fwhezfwhez/tcpx/tree/master/examples/modules/my-marshal
This is example of using your code.
server:
package main
import (
"fmt"
"github.com/fwhezfwhez/errorx"
"github.com/fwhezfwhez/tcpx"
"github.com/fwhezfwhez/tcpx/examples/modules/my-marshal/marshaller"
)
func main() {
srv := tcpx.NewTcpX(marshaller.ByteMarshaller{})
srv.AddHandler(22, func(c *tcpx.Context) {
var message []byte
mi, e := c.Bind(&message)
if e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
fmt.Println(mi.MessageID, string(message))
})
fmt.Println("listen on :7011")
srv.ListenAndServe("tcp", "localhost:7011")
}
client:
package main
import (
"fmt"
"github.com/fwhezfwhez/tcpx"
"github.com/fwhezfwhez/tcpx/examples/modules/my-marshal/marshaller"
"net"
)
func main() {
conn, e := net.Dial("tcp", "localhost:7011")
if e != nil {
panic(e)
}
var payload = []byte(`hello`)
buf, e := tcpx.PackWithMarshaller(tcpx.Message{
MessageID: 22,
Header: nil,
Body: payload,
}, marshaller.ByteMarshaller{})
_, e = conn.Write(buf)
if e != nil {
fmt.Println(e.Error())
return
}
select {}
}
server output:
listen on :7011
22 hello
from tcpx.
Also,you can use packx:
srv.AddHandler(23, func(c *tcpx.Context) {
var message []byte
mi, e := packx.Unpack(c.Stream, &message)
if e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
fmt.Println(mi.MessageID, string(message))
})
It print
23 hello
from tcpx.
Also, you can use your own marshaller:
srv.AddHandler(24, func(c *tcpx.Context) {
var message []byte
messageID, e := tcpx.MessageIDOf(c.Stream)
if e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
bodyRaw, e := tcpx.BodyBytesOf(c.Stream)
if e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
mm := marshaller.ByteMarshaller{}
if e := mm.Unmarshal(bodyRaw, &message); e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
fmt.Println(messageID, string(message))
})
it print:
24 hello
from tcpx.
Does all this help? I'v upgrade code https://github.com/fwhezfwhez/tcpx/tree/master/examples/modules/my-marshal
from tcpx.
I can't rebuild your error, because I can't see how you define server tcpx object.
// >>> this tcpx object
srv := tcpx.NewTcpX(marshaller.ByteMarshaller{})
// >>>>
fmt.Println("listen on :7011")
srv.ListenAndServe("tcp", "localhost:7011")
from tcpx.
first, thanks a lot.
i design a test, it ran good when server running at local machine, but it failed when server running at remote machine. maybe network plays it's role.
server:
package main
import (
"fmt"
"github.com/fwhezfwhez/errorx"
"github.com/fwhezfwhez/tcpx"
)
func OnConnect(c *tcpx.Context) {
fmt.Println(fmt.Sprintf("connecting from remote host %s network %s", c.ClientIP(), c.Network()))
}
func OnClose(c *tcpx.Context) {
fmt.Println(fmt.Sprintf("connecting from remote host %s network %s has stoped", c.ClientIP(), c.Network()))
}
func OnMessage(c *tcpx.Context) {
var message []byte
messageID, e := tcpx.MessageIDOf(c.Stream)
if e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
switch messageID {
case 22:
bodyRaw, e := tcpx.BodyBytesOf(c.Stream)
if e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
mm := tcpx.ByteMarshaller{}
if e := mm.Unmarshal(bodyRaw, &message); e != nil {
fmt.Println(errorx.Wrap(e).Error())
return
}
fmt.Println(string(message))
default:
fmt.Println("unexpected message:", messageID, message, "->", string(message))
}
}
func main() {
srv := tcpx.NewTcpX(tcpx.ByteMarshaller{})
srv.OnClose = OnClose
srv.OnConnect = OnConnect
srv.OnMessage = OnMessage
tcpx.SetLogMode(tcpx.DEBUG)
srv.ListenAndServe("tcp", ":7880")
}
client:
package main
import (
"fmt"
"github.com/fwhezfwhez/tcpx"
"math/rand"
"net"
"os"
"runtime"
"strings"
"sync"
"time"
)
var changen = make(chan []byte, 10)
var r *rand.Rand
func init() {
r = rand.New(rand.NewSource(time.Now().Unix()))
}
func generate(wg *sync.WaitGroup) {
for i := 1000; i < 50000; i++ {
fmt.Println(i)
b := strings.Repeat("a", rand.Intn(100))
changen <- []byte(b)
}
wg.Done()
}
func gogo(wg *sync.WaitGroup) {
tcpAddr, err := net.ResolveTCPAddr("tcp4", "localhost:7880")
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil{
time.Sleep(5 * time.Second)
os.Exit(1)
}
defer conn.Close()
for {
// write
gen := <- changen
buf, err := tcpx.PackWithMarshaller(tcpx.Message{
MessageID: 22,
Header: nil,
Body: gen,
}, tcpx.ByteMarshaller{})
_, err = conn.Write(buf)
if err != nil {
break
}
}
wg.Done()
}
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go generate(&wg)
wg.Add(1)
go gogo(&wg)
select {
}
}
from tcpx.
I've tried throw it on linux 64bit. And your code run well.
I wander, do you compile your code and throw it to the remote, or throw your code to the remote and compile remotely.
If you compilre away, make sure your remote machine has latest version of tcpx.
ssh <your machine>
go get -u github.com/fwhezfwhez/tcpx
Or, rebuild your binary file.
from tcpx.
This is I run your code
https://user-images.githubusercontent.com/36189053/71949520-cbe5fe00-320e-11ea-8c2f-9f1fe83b3f43.gif
from tcpx.
would you try to run server and client at different machines ?
from tcpx.
your code to the remote and compile remotely.
i throw server code to the remote and compile remotely. and i run client at local machine.
from tcpx.
@mickeystone 3Q, I tried and meet with the same question, a pull request to solve this has been merged.
You can update your tcpx version in both of your local machine and remote machine by
go get -u github.com/fwhezfwhez/tcpx
from tcpx.
thank you too, and tcpx is a very great framework!
keep moving on.
from tcpx.
Related Issues (20)
- [feature-asking] Can you normalize the name of the network package read interface function? HOT 1
- picture repo HOT 3
- [feature-asking]How tcpx works in distribution system?
- 有做分布式的计划吗? HOT 2
- [Promotion]Profile usage of anchor middleware
- 心跳具体要怎么配置? HOT 6
- 有时候解析包出错 HOT 10
- [Promotion] Provide url style routing way, help tcpx practice better!
- 当收到错误报文时,会产生fatal error: runtime: out of memory致命错误 HOT 1
- 需要新添加可自动检测指定时间内没发送心跳就下线 HOT 1
- 需要新增一个 可以获取客户端(非极端环境下)断开连接的userid HOT 1
- 需要新增一个 HeartBeatModeDetail 可重写的 HOT 1
- 会自动触发掉线 HOT 1
- [Promotion] Enable tls
- tcp client的例子跑一下就死了 HOT 2
- [enhancement-candidate] Graceful stop, graceFul restart practice bad
- connection pool high-availeble supporting HOT 2
- go get github.com/fwhezfwhez/tcpx go get github.com/fwhezfwhez/tcpx: no matching versions for query "upgrade"
- Specifies whether TCP can be established by proxy
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tcpx.