That’s good to know. I figured after 20+ years of learnings with Java serialization that a somewhat modern version would have the ability to reset the stream. This is required for large dynamic object models. Very surprising.
> On Dec 23, 2020, at 6:56 PM, 'Axel Wagner' via golang-nuts > <golang-nuts@googlegroups.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. >>>>>>>>> >>>>>>>>> -- >>>>>>>>> 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. >>>>>>> >>>>>>> -- >>>>>>> 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. >>>>>> >>>>>> -- >>>>>> 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. >>>>> >>>>> -- >>>>> 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. > > -- > 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/CAEkBMfFcE9fJvLaEB1oSRFaWOWWAOy%2BuZgO6NQs56O_1SxovzQ%40mail.gmail.com. -- 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/8CD82922-A4B7-43E7-BFE3-3AF23FFF6946%40ix.netcom.com.