Giter Site home page Giter Site logo

Comments (14)

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

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.

mickeystone avatar mickeystone commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

Does all this help? I'v upgrade code https://github.com/fwhezfwhez/tcpx/tree/master/examples/modules/my-marshal

from tcpx.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

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.

mickeystone avatar mickeystone commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

This is I run your code
https://user-images.githubusercontent.com/36189053/71949520-cbe5fe00-320e-11ea-8c2f-9f1fe83b3f43.gif

from tcpx.

mickeystone avatar mickeystone commented on July 30, 2024

would you try to run server and client at different machines ?
tcpx

from tcpx.

mickeystone avatar mickeystone commented on July 30, 2024

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.

fwhezfwhez avatar fwhezfwhez commented on July 30, 2024

@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.

mickeystone avatar mickeystone commented on July 30, 2024

thank you too, and tcpx is a very great framework!
keep moving on.

from tcpx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.