Server-Client Communication in Unity
Lars Wobus
Senior Animation Programmer @3D Interaction Technologies // I bring your 3D models to life on the web, desktop and mobile devices
#gamedevelopment?,?#unity3d?,?#csharp , #digitaltwin , #3d , #programming
Foreword
Hello and welcome back. This week I want to finish my little digression on the Chain of Responsibility design pattern and the ConcurrentQueue data structure. That means it's time to implement a simple TCP client and server.
Abstract
Listening to client and server messages is usually done via a separate thread so that the main thread is not blocked. Unfortunately, Unity is not thread-safe and calling the API from other threads was made impossible.
One solution to this problem is the combination of the Chain of Responsibility pattern and the ConcurrentQueue data structure.
Preparation
To keep the code as short as possible, we will use an existing library called SimpleTCP in our Unity project.
(Skip this section if you already know how to get Nuget packages and how to add DLLs in Unity projects)
Steps to Reproduce
(1) Create a new .Net project in Visual Studio.
(2) Depending on your platform, you may be able to select the target framework during creation. However, you can also change the target framework later by right-clicking the project and selecting Options. A window like the one in Figure 1 should now open. Here you can make the changes to the target platform.
(3) Select .Net Framework 4.5 and close the window afterwards.
(4) Right-clicking the project and selecting Manage Nuget Packages... will open another window, as shown in Figure 2. Search for SimpleTcp in the search bar and select Add Package.
(5) Now build your empty project once. Either in Debug or in Release mode. Afterwards you will find a file called SimpleTCP.dll in the bin/Debug or bin/Release folder of your project.
(6) Now copy the DLL into your Unity project. E.g. under Assets/Plugins folder or similar.
领英推荐
Design
For the communication between client and server, we first need some data classes. For better comprehensibility, we use the classes from article 6 again. But now they have some attributes and some properties. We will also reuse the base class from our Chain of Responsibility pattern (see Figure 3).
Next, we need two new data processing classes that will later represent our Chain of Responsibility (see Figure 4).
Now we can start implementing a TCP server. Thanks to the SimpleTcpServer class, our own class remains very clear (see Figure 5).
The same applies to our TCP client class (see Figure 6).
Last but not least, we need a central point where we can test our implementation (see Figure 7). For simplicity, this is all done in a single MonoBehaviour.
Inside the Start method, we ...
In the Update method, the received server messages are then finally consumed.
Final Words
In real-world use cases, the TCP server would likely be an independent application. The Unity application, on the other hand, would act as a TCP client that connects to the server and waits in a separate thread for incoming messages from the server.
Since the messages are passed to the main thread via the ConcurrentQueue before or after processing, the Unity API can also be called afterwards. E.g. to update real-time data in a dashboard.
That's it for today.
What do you think about this approach? Have you ever had such a use case? Or do you think that I have forgotten an important aspect, then please leave a comment.
And if you are interested in topics like game development, project organization or software design patterns, don't forget to press the Follow button on?my profile page?or add me as a contact. Not convinced yet? Well, maybe you will be once you read some of my?other articles.