I will definitely explore your ideas, thanks for the insights. I'll let you know how it turned out in the end :D
Thanks On Thu, 24 Dec 2020, 06:59 Axel Wagner, <axel.wagner...@googlemail.com> wrote: > On Thu, Dec 24, 2020 at 6:35 AM Artur Vianna <lordhowen...@gmail.com> > wrote: > >> Exposing the bytes would hurt the abstraction. >> > > I strongly disagree with this. Exposing the bytes would improve the > abstraction, by making the transmission- and encoding method orthogonal. > And as I said, you can still provide just as convenient a wrapper around it. > > >> I will certainly look into Json and maybe MessagePack. But first i may >> fiddle with the gob source code, if my sanity allows it. If i can control >> when the type information is sent i may be able to fix this without >> changing the API. The ideal enconding would be a stateless gob, with the >> proper decoding/encoding "machines" set on either side when you call >> gob.Register, but i'm not sure of the feasibility of that. >> > > Sure, that's definitely possible. I factored that in, when I said "I think > it's far less effort to just use a different format than trying to make > this work with gob". > > But, of course, you do you. :) The decision of what API to expose and what > encoding scheme to use and how much work you are putting into what piece is > ultimately up to you :) > > >> >> On Wed, 23 Dec 2020, 21:55 Axel Wagner, <axel.wagner...@googlemail.com> >> wrote: >> >>> On Thu, Dec 24, 2020 at 1:08 AM Artur Vianna <lordhowen...@gmail.com> >>> wrote: >>> >>>> Before using gob was using encoding.BinaryMarshaler, but that would >>>> mean the user of the api would need to implement a MarshalBinary for every >>>> type, which is kind of cumbersome. >>>> >>> >>>> An option might be to let the user choose gob, BinaryMarshaler or Json >>>> etc to best fit the use case, but that takes the simplicity of only gobs >>>> away. >>>> >>> >>> I am all in favor of API simplicity, but gob just isn't super useful for >>> this. Not to repeat myself, but you should really at least try JSON - it >>> provides exactly the same convenience as gob, but doesn't suffer these >>> problems. It might have a bit more overhead and might even be costlier to >>> encode - but the savings from being able to eliminate duplicate effort >>> should offset that (and I'm not even super convinced - I don't think gob is >>> the most well-optimized encoding in the stdlib). >>> >>> But IMO, if you provide an API, the best solution is to a) just use >>> `[]byte` at the base-layer and then b) provide convenience-wrappers around >>> that for other formats. This lets the users decide what they want (they >>> might want something completely different anyway) while still providing a >>> decently convenient API for simple uses. >>> >>> >>>> >>>> I did try your solution to reset the client too but i'm getting >>>> inconsistent behaviour, in one server it works and in another it doesn't >>>> ("corrupted data or unknown type"). I think synching the server and client >>>> will be error prone, while also increasing the use of network. >>>> >>>> The easiest solution now is to label the package for ≤32 players and >>>> test alternative encodings that keep the API as clean as with gob. I took a >>>> look at flatbuffers but it will be cumbersome for the user to create the >>>> builders, and i really wanted the simplest possible API. >>>> >>>> Maybe i should try UDP Broadcast too and see what happens, probably >>>> chaos :D >>>> >>>> >>>> On Wed, 23 Dec 2020, 20:36 Axel Wagner, <axel.wagner...@googlemail.com> >>>> wrote: >>>> >>>>> No, it wouldn't. Because the encoder keeps state about which >>>>> type-information it already sent and wouldn't sent it again - causing the >>>>> client to be unable to decode. So you'd also need a new encoder on the >>>>> server. And at that point, you're back to the status quo, with one encoder >>>>> per client and the duplication of encoding effort. >>>>> >>>>> A solution would, perhaps, be if the gob API would give you a way to >>>>> send *only* the type-info (so you could, if the connection breaks, create >>>>> a >>>>> new encoder, send all the type info, and *then* multicast the encoded >>>>> values). But it doesn't. >>>>> >>>>> Really, I think it's far less effort to just use a different format >>>>> (and I would maintain that even json would probably be fine) than trying >>>>> to >>>>> make this work with gob :) >>>>> >>>>> On Thu, Dec 24, 2020 at 12:20 AM Matthew Zimmerman < >>>>> mzimmer...@gmail.com> wrote: >>>>> >>>>>> If you would "reset" each client with a new decoder each time you >>>>>> make a new encoder, everything should work fine. Just would take some >>>>>> coordination. >>>>>> >>>>>> On Wed, Dec 23, 2020, 6:08 PM Artur Vianna <lordhowen...@gmail.com> >>>>>> wrote: >>>>>> >>>>>>> I will look into other protocols, although for now the performance >>>>>>> is not an issue in servers with less than 100 players. >>>>>>> >>>>>>> The problem with io.MultiWriter is that a player inside the group >>>>>>> may disconnect or a new player may come in. This means a new >>>>>>> io.MultiWriter >>>>>>> must be created each time you dispatch, since the group may have >>>>>>> changed in >>>>>>> the meantime. This would also need a new encoder and then the "duplicate >>>>>>> type received" happens. >>>>>>> >>>>>>> On Wed, 23 Dec 2020, 19:58 'Axel Wagner' via golang-nuts, < >>>>>>> golang-nuts@googlegroups.com> wrote: >>>>>>> >>>>>>>> The issue with that approach is that gob keeps state about which >>>>>>>> type-information it still has to send. So if you encode to, say, a >>>>>>>> bytes.Buffer, it would encode all type-info on every message sent, >>>>>>>> which is >>>>>>>> a significant overhead. >>>>>>>> TBH, I don't understand why `io.MultiWriter` wouldn't work. It >>>>>>>> would be helpful to see the code that causes the error message OP is >>>>>>>> seeing. >>>>>>>> >>>>>>>> However, really, gob just doesn't provide a good API for this sorta >>>>>>>> thing, as mentioned. The format itself is fine, but the stateful >>>>>>>> connection >>>>>>>> means that if you don't want to write *exactly* the same data in >>>>>>>> exactly >>>>>>>> the same order to all connections (which can perform poorly and lead to >>>>>>>> operational problems with timeouts and intermittently lost connections >>>>>>>> and >>>>>>>> the like), you are going to have a bad time. >>>>>>>> You honestly would fare better with a full-fledged RPC framework >>>>>>>> such as gRPC. Or, if you don't want the overhead of its IDL, even json. >>>>>>>> Because at least the "encode once, send to each client" is trivial to >>>>>>>> solve >>>>>>>> with that. >>>>>>>> >>>>>>>> But, that's just my 2¢ :) >>>>>>>> >>>>>>>> On Wed, Dec 23, 2020 at 11:43 PM Robert Engels < >>>>>>>> reng...@ix.netcom.com> wrote: >>>>>>>> >>>>>>>>> Yes, that is why you need to create your own protocol. Use the gob >>>>>>>>> to encode to a buffer then send the buffer on each of the connections >>>>>>>>> using >>>>>>>>> your protocol. >>>>>>>>> >>>>>>>>> On Dec 23, 2020, at 4:19 PM, Matthew Zimmerman < >>>>>>>>> mzimmer...@gmail.com> wrote: >>>>>>>>> >>>>>>>>> >>>>>>>>> My understanding is that gob streams are unique. >>>>>>>>> >>>>>>>>> From https://golang.org/pkg/encoding/gob/ >>>>>>>>> "A stream of gobs is self-describing. Each data item in the stream >>>>>>>>> is preceded by a specification of its type, expressed in terms of a >>>>>>>>> small >>>>>>>>> set of predefined types." >>>>>>>>> >>>>>>>>> In my own rudimentary understanding/terms, it sends the struct >>>>>>>>> definition once, then uses shorthand for it afterwards. E.g, how many >>>>>>>>> bytes and what order. If you mix and match streams that send >>>>>>>>> definitions >>>>>>>>> in different orders, then chaos ensues. >>>>>>>>> >>>>>>>>> I think this is why people use other encoders in the scenario >>>>>>>>> you're taking about. For a one to one stream gob works great, but in >>>>>>>>> this >>>>>>>>> multi scenario I don't think it does. >>>>>>>>> >>>>>>>>> Matt >>>>>>>>> >>>>>>>>> On Wed, Dec 23, 2020, 5:07 PM Artur Vianna <lordhowen...@gmail.com> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> If i create a bytes.Buffer and a gob.Encoder, each time i write >>>>>>>>>> to a group of connections i get "duplicate type received" and if i >>>>>>>>>> try and >>>>>>>>>> reuse the encoder, i get "corrupted data" and "unknown type". >>>>>>>>>> It seems i can't use both net.Conn.Write and gob.Encoder.Encode >>>>>>>>>> in the same connection, i will try always encoding to a buffer in >>>>>>>>>> both >>>>>>>>>> unicast and multicast like you said and report if it works. >>>>>>>>>> >>>>>>>>>> On Wed, 23 Dec 2020, 18:49 Robert Engels, <reng...@ix.netcom.com> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> You need to encode once to a byte array then send the byte array >>>>>>>>>>> on each connection. >>>>>>>>>>> >>>>>>>>>>> On Dec 23, 2020, at 3:45 PM, meera <lordhowen...@gmail.com> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I am trying to create a package for game servers using gob. The >>>>>>>>>>> current approach is an application level multicasting over TCP, >>>>>>>>>>> having a >>>>>>>>>>> gob encoder and decoder for each player connection, and set up a >>>>>>>>>>> goroutine >>>>>>>>>>> to receive and another to dispatch for each one. The code for the >>>>>>>>>>> dispatcher is here. But summarized, it simply receives data from a >>>>>>>>>>> channel >>>>>>>>>>> and encodes it. >>>>>>>>>>> >>>>>>>>>>> The problem is that if i want to transmit a single piece of data >>>>>>>>>>> to all players, this piece of data is encoded again and again for >>>>>>>>>>> each >>>>>>>>>>> connection, doing duplicate work. With less than 100 players this >>>>>>>>>>> is not a >>>>>>>>>>> problem, but with 300+ my machine is at almost 100% usage and the >>>>>>>>>>> profiler >>>>>>>>>>> shows that most of it is spent on encoding. Here's the issue on >>>>>>>>>>> github. >>>>>>>>>>> >>>>>>>>>>> I tryied using a io.MultiWriter but gob complains of duplicate >>>>>>>>>>> type received, and if i try to write the raw bytes from the >>>>>>>>>>> gob.Encoder i >>>>>>>>>>> get corrupted data. An option is using UDP Broadcasting but since >>>>>>>>>>> gob >>>>>>>>>>> expects a stream, i'm affraid i will run into unexpected behavior >>>>>>>>>>> when >>>>>>>>>>> packets start to be lost and fragmented. >>>>>>>>>>> >>>>>>>>>>> Does gob expect a single encoder and decoder to own the stream? >>>>>>>>>>> Not allowing two encoders on the server for one decoder on the >>>>>>>>>>> client? >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>>> Google Groups "golang-nuts" group. >>>>>>>>>>> To unsubscribe from this group and stop receiving emails from >>>>>>>>>>> it, send an email to golang-nuts+unsubscr...@googlegroups.com. >>>>>>>>>>> To view this discussion on the web visit >>>>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/0562184e-bbcc-44c9-adbf-37e8d5411c7cn%40googlegroups.com >>>>>>>>>>> <https://groups.google.com/d/msgid/golang-nuts/0562184e-bbcc-44c9-adbf-37e8d5411c7cn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>>>>>>> . >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>> Google Groups "golang-nuts" group. >>>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>>> send an email to golang-nuts+unsubscr...@googlegroups.com. >>>>>>>>>> To view this discussion on the web visit >>>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/CAE%3DAWBXN46idvqUbCsGs%2BZbZt%2BCj4MowJ4Ozj3_U9_6-68OWDw%40mail.gmail.com >>>>>>>>>> <https://groups.google.com/d/msgid/golang-nuts/CAE%3DAWBXN46idvqUbCsGs%2BZbZt%2BCj4MowJ4Ozj3_U9_6-68OWDw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>>>>>> . >>>>>>>>>> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "golang-nuts" group. >>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>> send an email to golang-nuts+unsubscr...@googlegroups.com. >>>>>>>>> To view this discussion on the web visit >>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/214752B6-2666-4892-A9B8-E4BC4127FD42%40ix.netcom.com >>>>>>>>> <https://groups.google.com/d/msgid/golang-nuts/214752B6-2666-4892-A9B8-E4BC4127FD42%40ix.netcom.com?utm_medium=email&utm_source=footer> >>>>>>>>> . >>>>>>>>> >>>>>>>> -- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "golang-nuts" group. >>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>> send an email to golang-nuts+unsubscr...@googlegroups.com. >>>>>>>> To view this discussion on the web visit >>>>>>>> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGWtULh8Q3Jqu_gq5m5Si4PvJ1oVSZY7DVhu%3D6hGK83bg%40mail.gmail.com >>>>>>>> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGWtULh8Q3Jqu_gq5m5Si4PvJ1oVSZY7DVhu%3D6hGK83bg%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>>>> . >>>>>>>> >>>>>>> -- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "golang-nuts" group. >>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>> send an email to golang-nuts+unsubscr...@googlegroups.com. >>>>>>> To view this discussion on the web visit >>>>>>> https://groups.google.com/d/msgid/golang-nuts/CAE%3DAWBUsmp2sbiEh%3D3z0cC9EhjLig%2B8exXyA05YngBJ-tsC_uA%40mail.gmail.com >>>>>>> <https://groups.google.com/d/msgid/golang-nuts/CAE%3DAWBUsmp2sbiEh%3D3z0cC9EhjLig%2B8exXyA05YngBJ-tsC_uA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>>> . >>>>>>> >>>>>> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAE%3DAWBWmiQbVBxQ2FcWguzbd7Y62LUjmQ%3DY0qKe%3D4M0WKgoubg%40mail.gmail.com.