UdpClub banner

UdpClub

17 devlogs
21h 14m 28s

A library for C# designed to help speed up the development of UDP networking apps.

Demo Repository

Loading README...

averytoad65

Shipped this project!

Hours: 21.24
Cookies: šŸŖ 537
Multiplier: 25.28 cookies/hr

(copied from the README, because of time constraints irl)
UdpClub is a C# library, which acts as a wrapper around the UdpClient class, with a few extra utilities. UdpClub automatically handles parsing byte data into packages for you, as well as RPC calls and a standardized way to create network packages for your project.

The project features a demo project known as ā€œChatAppā€, it can be found as one of the attachments on the 1.0.0 release tab on GitHub.

averytoad65

18 minutes? Surely I must’ve done more than fix kicking.. maybe the time I spent testing the Messaging App and updating the README heavily played into this time. But that’s small stuff. I have made one final fix, which should hopefully mark the demo app as complete.. kicking! Previously, as you may have seen in my previous devlog, kicking didn’t refresh the users list on the server-side, now it does. This should hopefully prevent the app from getting rejected for bugs. Guess we’ll have to wait and see though. Time to ship! Thank you to everyone who has read even one line of these devlogs.

Attachment
0
averytoad65

Well, what can I say.. the demo is done? At least everything I thought to test is functioning well, so… might ship this project really soon. It’s been fun! Been super cool to make my own wrapper library for the C# UdpClient. Who knows, maybe I can actually use this project for games or something, I mean I got package and RPC Handling implemented. Of course, I would like to clean up the codebase sometime, but, who knows when I’ll get to that.
So the final bits of polish I added since last devlog was getting rid of duplicate ā€œx left the chat.ā€ messages when a user got kicked and adding a ā€œx GOT KICKEDā€ message to the server client.
Happy coding :D

Attachment
1

Comments

averytoad65
averytoad65 about 1 month ago

I might be blind- I completely missed the server user list not updating..

averytoad65

I swear to god I always have the weirdest bugs with the weirdest solutions in this project. Anyways! Almost 4 hours elapsed, let’s see what I managed to do in that time…

New stuff / fixes

Server Menu

The server application no longer just blocks inputs to the startup window, instead it now shows a window similar to the client interface, except you can’t message. But to make up for that, if you are the server, you can kick clients! Why? It means more features, which means more time to work on this project. So there’s that.

Force Disconnect Package

So, this plays directly into the moderation feature. The issue was that I couldn’t find a way to force a remote UdpClient to disconnect, hence I had to make a little workaround. The ForceDisconnectPackageis built into UdpClub now and it automatically disconnects a client from the server. Beware though, it doesn’t work on servers.

No more duplicates (i hope)

I fixed a major bug that has been plaguing the demo project since I got the Client UI to work, duplicate names in the users list. And I finally figured out how to fix it, I tried everything from locking the memberList variable (since it might be an issue with multi-threading), but to no effect. However, delaying the function by 50ms seems to do the trick. I figured this out when I was debugging the project and couldn’t replicate the bug at all, whereas it would constantly appear without the debugger. Why? I have no idea lmao.

Look at the attachments

I put a few neat things in the attachments this time around, first off the obvious, the server UI. But I also put in the new code for adding a member with locking (just in case) and timeouts, and a demonstration of what kicking looks like!
Have a nice day and happy coding!

Attachment
Attachment
0
averytoad65

Time for debugging!

After having loads of fun using the UdpClub demo with my friend who lives all the way in America, I had made a realization that I should’ve made long ago… the error handling is practically non-existent. That’s a pretty major issue if you ask me. So I finally did something about it. Now, whenever PackageHandler has an error, it throws an exception and keeps running. This is mainly so applications don’t freeze when an error such as a SocketException occur. I could handle this better, and I probably will. But for now this rudimentary system is very helpful for me. Especially since it lets the demo run more consistently.

Attachment
0
averytoad65

Few changes since I last checked in an hour ago.. So what’s new?

I figured out markdown!

So.. turns out you can use markdown on here? An extension that was showcased in the show and tell made me aware of this. It’s super cool, tbh. Gonna be using this way more.

Features

Join / Leave messages

Now, when a user joins or leaves the server, a little message is sent into the chat! Making it feel less empty and also letting you sort of timestamp when someone leaves/rejoins. Neat, isn’t it? I think it is. If you feel another way, well then I quite frankly don’t know what to tell you. Moving on!

General messenging

As the previous header, and the screenshot that I definitely put a lot of thought into, may imply… messenging works! Now you can send messages to other clients and have a little chat. Well, ok, not really in this case, I don’t wanna engage in port-forwarding right now, so I have only tested it on localhost with myself, but it works pretty darn well from what I’ve tested, except one bug where the user list duplicates an entry, dunno where it’s wrong, but I’ll fix it eventually!

RunOnServer parameter in RpcPackages

This was originally intended to be a bug fix for the Leave Message duplicating before I figured out the actual cause, but since I feel like somebody will find utility in it, might as well leave this little scrappy feature in. Enjoy, potential users of this library, you can now force a server to never run an RPC.

Small fixes in the client logic

During testing I had an issue where the server froze up a few times. The cause? C# throws an exception when you try to invoke an Action that hasn’t been subscribed to, and somehow my code doesn’t output that exception (maybe cuz it’s running on a different thread? idk). In any case, that is fixed now, and the server runs as well as it can. How good is that? I have no idea. Gotta do more testing.

Attachment
0
averytoad65

Alrighty, small check in again.. I managed to implement users syncing, so now when you connect to the server, you get a small RPC call that gives you a list of every user that is currently connected to the server. Now I just need to make it, so that on the backend, the user leave message is properly communicated. Maybe I should switch it from an RPC to a Package then. Who knows. For now, I do mainly wanna get messaging working, because that’s the main selling point of this app.

Attachment
0
averytoad65

Ok, ok. So, I didn’t want to deal with the termianl for the demo project anymore, so I kinda just.. rebuilt the entire thing in Windows Forms. Right now very little works, you can start a server instance and a client instance. The client can input their username and then the main messaging UI loads. Nothing crazy, just took a bit because Rider’s UI builder doesn’t like me. But, hey, soon I can build some logic for sending messages, sending the user list to new clients (right now if the user ā€œtestā€ logged in after ā€œaveryā€, only ā€œaveryā€ would see both users in the user list). I also need to implement leaving, because right now that doesn’t have any implementation at all… Also a server UI.. After that? Not sure. Maybe I can add moderator operations to the server UI. Guess we’ll see. I am also kinda writing this in a rush, so excuse me if my sentence structure changes mid-sentence. See you and happy coding!

Attachment
0
averytoad65

Alrighty, so, I’m a bit hazey on what I actually did in this almost hour and a half timeframe, so here goes nothing.
I simplified the invokation of RPCs! Now you just have to run RpcManager.BroadcastRpc(…) to run your RPC on the network. It’s nothing special, practically just a wrapper that makes an RpcPackage and throws it through PackageHandler, but it’s nice to have nonetheless. In bigger news, I got kind-of sick of always having to reference ā€œtypeof(MyPackage)ā€ when making a package class, so, I made the GenericPackage class, which acts as an abstraction layer on top of the regular BasePackage. It allows you to create packages way quicker and easier, since now you only have to specify your packet’s class name once, and the GenericPackage does the rest! It’s so nice to have, especially since a large bug I had in the demo project was because I wrote ā€œtypeof(AuthPacket)ā€ instead of ā€œtypeof(AuthReturnPacket)ā€ in my AuthReturnPacket class, making it so the AuthReturn never got interpreted. The new package structure, using the generic package class, is so much cleaner (see second screenshot). Don’t worry, though, you can still manually create a class on top of BasePackage if you’d like, nobody’s stopping you. And that’s about it, I think. Super fun working on this project for a bit and I’m getting a tad bit closer to shipping. I also hope I can show this project off at the Show and Tell tonight, guess we’ll see. See ya!

Attachment
Attachment
0
averytoad65

We got a logo now! Whipped up this cool little network of circles, because I thought it’d fit the project really nicely. Also I fixed a bug where every RPC in the project would get called if you called a single one. i.e. if you had the RPCs ā€œUserJoinMessageā€, ā€œUserLeaveMessageā€ and ā€œUserEmojiReactā€ and you called the RPC for ā€œUserJoinMessageā€ it would actually trigger all 3 RPCs. That is now fixed, silly me. Also I have swapped a few more debug-prints for the DebugPrintln function. Yay! Happy coding and thanks for reading!

Attachment
Attachment
0
averytoad65

RPCs work! I repeat, they fully work! I have freaking done it! I am so happy with myself for managing to fix RPCs so quickly - only took me 24 minutes, huh. I have also made some changes to some not-so-relevant parts of the source code, like replacing lots of the aforementioned statements that I wrapped in ā€œ#if DEBUGā€ to use my DebugPrint/DebugPrintln functions. But, back to the main course, I managed to figure out a nasty bug in parsing RPCs that would cause the network thread to hang indefinitely because of an unhandled exceptions (thanks, Rider Debugger for pointing that out to me..)
And.. yeah! I guess it’s time to clean up some code, write the demo project and maybe look into more parameters? Who knows! What I know for sure is that I’m gonna blast Good Kid music now. Cheers!

Attachment
Attachment
0
averytoad65

Another day, another… four hours of work? Damn. I didn’t even realize. Alright, well, here’s what I spent my time doing today, and what I will continue to do because I want this project to freaking work.
So! I worked on a little demo project, because I planned on shipping an initial release of UdpClub soon. But there’s a slight issue with that, the app I want to make for my demo is a basic messaging app between multiple clients, only issue is that I want to include things like a welcome message when a user joins and some other stuff where an RPC with a parameter would be lovely. Only issue is… I can’t do that. For something as simple as a welcome message I just simply want to be able to call an RPC and have it invoke everywhere. Annoyingly, I was too lazy to implement that when my mind understood the awful code I wrote! Now I have to dive back in and debug it. And that’s what I’ve been doing! Well, ok, I did also work on the basic demo project, but who cares about that. Anyhow, during these four hours of debugging my code I have noticed how incredibly fragile the system is and how badly I want to remake it to be way clearer to debug and use, so, uh… RPC rewrite today? Maybe? Who knows. Though, today I will probably only get RPCs with one parameter working and like.. replace all my manual #if DEBUG /* print */ #endif statements with an abstraction, which I called ā€œDebugPrintā€. Anyways, that’s basically all. Let’s hope that I can get this resolved ASAP when I’m home and not bothered by school, the new NullReferenceException is definitely promising… Cheers!

Attachment
0
averytoad65

Not a lot of changes for right now, but that’s mainly, because I spent my time making an EXE for SWP so the ship doesn’t get rejected again.
But, I implemented a small feature.. loopbacks! A loopback lets you specify if the RPC Package should return to the sender once the client sends it to the server, this is useful so there is less confusion about if you should run the RPC function locally as well, or if the package comes from the server-side. It also has practical usages, but I can’t think of any examples off the top of my head.
Next up is (hopefully) documentation and cleanup of the existing RPC handling code. Let’s see how that goes.
Happy coding and thank you for reading!

Attachment
0
averytoad65

… so I spent 3 hours implementing RPCs (Remote Procedure Calls), and boy oh boy… it’s a mess, like most things in this!
So, let’s dive into it, shall we?
At first I began with writing a RPC Attribute class, plain and simple, afterwards a small RPCManager to ensure that I can easily call RPCs from anywhere. Then followed a small RPC Package to make it easy for the server to communicate that the clients should execute a function, all well and good… Until it came to implementing how you’re supposed to run the function. Granted, I took the easy way out: only allow static methods. But I don’t want that to be the case forever, I want this to eventually run on object instances too, but that’s gonna take a bit for me to do. Probably past the time limit of this whole Flavortown thing, so, screw it. Anyways, so after implementing all that, I was met with an issue: RPCs weren’t registering. So, what did I mess up? Well I had the call to subscribe my RPC to the RPCManager in the RPCAttribute constructor, should work, right? Well, the developers of roslyn (the C# compiler) decided to throw me a giant ā€œF**k you,ā€ because the constructor for an Attribute is never called until you somehow reference the RPC via MethodInfo.GetCustomAttributes() and whatnot… suffice to say it took me a bit to figure out.
But, hey, I finally did it. Now you can register static functions are RPCs with a specific ID and you can easily call ā€˜em through the server, now all I have left to do is make the communication system with the RPCPacket work in a way that a client can request to execute a RPC to the server and then the server can spread that message to other clients.. and I should definitely get parameters working. But, I think first I’ll focus on cleaning up this steaming mess of redundant calls and whatnot, and heavy documentation, right now only god and I know what this code does, not very sustainable.

Anyhow, happy coding!

Attachment
1

Comments

sl4shed
sl4shed about 2 months ago

seems interesting. keep up the work!

averytoad65

gotta make this quick, sorry..

  • Added IPEndPoint to BasePackage
  • Added two new test packets to Test projects
  • Fucked up with the gitignore for packages and whatnot (gonna fix that immediately tmr)
  • Updated PackageHandler to include new functions for sending packets
  • update predicate for finding correct BasePackage constructor w/ correct new parameters and debugging stuff
  • more prolly

thanks for reading!

Attachment
Attachment
Attachment
1

Comments

averytoad65
averytoad65 2 months ago

ok so turns out that you can just clone the project and it will download NUnit automatically even without the packages dir, good to know! although I should probably also test this on my laptop to be 100% sure…

averytoad65

I feel like one of the best programmers of all time right now - my complex workaround for making a dynamic package library somehow worked on the first try! I managed to finally make it so you can easily initialize a UdpClientApp or UdpServerApp and send packages from it! And it just… works! As long as you make a registry for the packages which adds them to PackageHandler.Packages using PackageHandler.RegisterPacket(…) but that’s beside the point. What I mean to say is that, the fundemental principle of my application is done, a more simplistic way to send and parse data packets over a network. Can it be optimized? 100%. Will I optimize it? Perhaps, we’ll see how much time I have for that until I ship the project. For now though, I will happily enjoy this win and dance around like a silly goober to ā€œNa Na Na (Na Na Na Na Na Na Na Na Na)ā€ by My Chemical Romance. See ya, and thank you, you lovely individual, for reading this!

Oh, also, if you care to check out what I made and you can’t find the GitHub repo, you can find the project source code at: https://github.com/averyocean65/UdpClub/

Attachment
Attachment
0
averytoad65

… so turns out the fix for the communication issue between the Client and Server was simply because the client was using the IP EndPoint used in ā€œUdpClient.Receive(…)ā€ to communicate messages, which apparently doesn’t work for sending stuff to the server - the more you know! Thanks C#.

Anyhow, the issue is fixed now using a simple if-else statement lol. Took me about 3 minutes to figure out.

I also worked on a package class as well as a PackageMap, I also took baby steps in creating the PackageHandler. Now, unfortunately, I am not sure how to build a modular system for building and identifying packets, so I’ll have to get back to my mental drawing board until something comes to mind.

Attachment
0
averytoad65

I finally got a basic framework running to send data between a server and client via the UDP protocol. I am extremely happy to see that I got it up and running from only an hour of work. Unfortunately there is a bug in the package handling, as the server and client should constantly send packages to each other, so I have to do some debugging to see what’s going wrong. Very strong start though! Hope I can get the Package and Package Manager classes implemented tomorrow if I manage to iron this bug out.

Attachment
0