Giter VIP home page Giter VIP logo

networker's Introduction

Build status NuGet

Networker

A simple to use TCP and UDP networking library for .NET, designed to be flexible, scalable and FAST.

Supported Frameworks

  • .NET Standard 2.0
  • .NET Framework 4.7+ for Unity

Features

Installation

NuGet Package Manager

Install-Package Networker

You must then install one of the following formatters

ZeroFormatter

Install-Package Networker.Extensions.ZeroFormatter

MessagePack

Install-Package Networker.Extensions.MessagePack

Protobuf-net

Install-Package Networker.Extensions.ProtoBufNet

JSON (Utf8Json)

Install-Package Networker.Extensions.Json

Tutorial - Creating a Basic Unity Multiplayer Game with Networker

Get started with this tutorial written by the library developer Mark Eastwood

Example

Creating a server is easy..

var server = new ServerBuilder()
                .UseTcp(1000)
                .UseUdp(5000)
                .RegisterPacketHandlerModule<DefaultPacketHandlerModule>()
                .RegisterPacketHandlerModule<ExamplePacketHandlerModule>()
                .UseZeroFormatter()
                .ConfigureLogging(loggingBuilder =>
                                    {
                                        loggingBuilder.AddConsole();
                                        loggingBuilder.SetMinimumLevel(
                                            LogLevel.Debug);
                                    })
                .Build();

server.Start();

You can handle a packet easily using dependency injection, logging and built-in deserialisation.

public class ChatPacketHandler : PacketHandlerBase<ChatPacket>
{
	private readonly ILogger<ChatPacketHandler> _logger;

	public ChatPacketHandler(ILogger<ChatPacketHandler> logger)
	{
		_logger = logger;
	}

	public override async Task Process(ChatPacket packet, IPacketContext packetContext)
	{
		_logger.LogDebug("I received the chat message: " + packet.Message);

		packetContext.Sender.Send(new ChatPacket
		{
			Message = "Hey, I got your message!"
		});
	}
}

networker's People

Contributors

erictuvesson avatar markiodev avatar morganmoon avatar snarlynarwhal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

networker's Issues

ArgumentOutOfRangeException

Something strange happens here ... need help, I can reproduce the failure

fail: Networker.Client.ClientPacketProcessor[0]
System.ArgumentOutOfRangeException: Index and count must refer to a location within the buffer.
Parameter name: bytes
at Networker.Client.ClientPacketProcessor.Process(Byte[] buffer, ISender sender) in C:\Users\admin\Source\Repos\Networker\Networker\Client\ClientPacketProcessor.cs:line 134
at Networker.Client.ClientPacketProcessor.Process(Socket socket) in C:\Users\admin\Source\Repos\Networker\Networker\Client\ClientPacketProcessor.cs:line 70

How to use with Unity?

I feel dumb for asking this, but building a .dll file for Unity doesn't work, because Unity says that it has errors and unloads it.

Unloading broken assembly Assets/Plugins/Networker/Networker.dll, this assembly can cause crashes in the runtime

Server Send does not work

Hi,

I have got stuck in a weird situation. I want to initiate a send from the server side to all of the clients. So logically this should work:

                private IServer _server
                 ...
                var connections = _server.GetConnections().GetConnections();
               
                foreach (ITcpConnection connection in connections)
                {
                    connection.Socket.Send(Encoding.ASCII.GetBytes("COMMAND1"));
                }

But client doesn't receive this command.

Now if I save the server context somewhere and reuse it later it works:

private ISender _sender;

ServerPacketHandler_OnProcess(object sender, string e)
{
            _sender = (sender as IPacketContext).Sender;
}

Now this one will work :

                _sender.Send<string>("COMMAND1");`

What is the correct way of initiating a send from the server. Its not in the example and tests either.

Version 3

Is almost ready! Subscribe here for notifications

Unable to resolve service for type 'Networker.Common.Abstractions.IPacketSerialiser'

Hi,
I'm trying to play with Networker, so I just installed this package, then I set a simple server like this

    public sealed class UdpServer
    {
        private readonly IServer _server;
        
        public UdpServer (int port)
        {
            _server = new ServerBuilder().UseUdp(port).RegisterPacketHandlerModule<PacketHandler>().Build();
        }

        public void Start ()
        {
            _server.Start();
            Console.WriteLine($"UdpServer running on ${_server}");
        }
    }

And as soon as I instanciate UdpServer (not even calling Start) i got this error:

Unhandled Exception: System.InvalidOperationException: Unable to resolve service for type 'Networker.Common.Abstractions.IPacketSerialiser' while attempting to activate 'Networker.Server.ServerPacketProcessor'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType, ServiceProvider serviceProvider)
at System.Collections.Concurrent.ConcurrentDictionaryExtensions.GetOrAdd[TKey,TValue,TArg](ConcurrentDictionary2 dictionary, TKey key, Func3 valueFactory, TArg arg)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at Networker.Server.ServerBuilder.Build()
at Survixel.Server.Networking.UDP.UdpServer..ctor(Int32 port) in C:\Users\alexr\Prog\C#\Survixel.Server\Survixel.Server.Networking\UDP\UdpServer.cs:line 13
at Survixel.Server.Core.Program.Main() in C:\Users\alexr\Prog\C#\Survixel.Server\Survixel.Server.Core\Program.cs:line 10

ClientDisconnected problem

Hi just tested your library and found a issue about this event, ClientDisconnected on server never trigger.
There is a second problem, there is no ClientConnected and Close/Disconnect on client side

example:

``

    public ApisServer(string host, int port)
    {
        Host = host;
        Port = port;
        server = new NetworkerServerBuilder()
            .UseIpAddresses(new[] {host}).UseConsoleLogger().UseTcp(port)
            .RegisterPacketHandler<CL_Login, LoginHandler>()
            .Build<DefaultServer>();

        server.ClientConnected += ClientConnected;
        server.ClientDisconnected += ClientDisconnected;
    }

    private void ClientDisconnected(object sender, TcpConnectionDisconnectedEventArgs e)
    {
        Logger.Debug("Client disconnected {0}", e.Connection.Identifier); // Never trigger
    }

    private void ClientConnected(object sender, TcpConnectionConnectedEventArgs e)
    {
        Logger.Debug("Client connected {0}", e.Connection.Identifier);
    }

``

Suggestion: Decouple packet handler from packet serializer

If an application has a lot of packets and the developer must create a handler for each packet, it might get tedious, especially if a group of packet handlers have the same dependencies.

Ideally, related packets that require similar dependencies would get processed by the same handler. For example, in a game, all combat packets could get handled by CombatHandler. Of course if this class grows unwieldy, a developer could always break it all the way down to the traditional 1:1 relationship, if desired.

If the packet processor handled deserialization and the handler just processed the packet, then PacketHandlerBase<T> could get replaced by IPacketHandler<T> which would just require the Process method. This way, a concrete implementation could implement any number of IPacketHandler<T> interfaces.

What do you think?

UdpClientListener中监听强制使用了127.0.0.1,不适用于多网卡环境

在UdpClientListener中

 public UdpClientListener(ServerBuilderOptions options,
            ILogger<UdpClientListener> logger,
            IServerPacketProcessor serverPacketProcessor,
            IServerInformation serverInformation)
        {
            this.options = options;
            this.logger = logger;
            this.serverPacketProcessor = serverPacketProcessor;
            this.serverInformation = serverInformation;

            endPointPool = new ObjectPool<EndPoint>(this.options.UdpSocketObjectPoolSize);

            for (var i = 0; i < endPointPool.Capacity; i++)
                //endPointPool.Push(new IPEndPoint(IPAddress.Loopback, this.options.UdpPort));
                endPointPool.Push(new IPEndPoint(BindIPAddress, this.options.UdpPort));
        }
 public void Listen()
        {
            client = new UdpClient();
            client.ExclusiveAddressUse = false;
            client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            
            //临时处理,后续使用option传入网卡地址
            //endPoint = new IPEndPoint(IPAddress.Loopback, options.UdpPort);
            endPoint = new IPEndPoint(BindIPAddress, options.UdpPort);
            client.Client.Bind(endPoint);
...
}


2.1 Refactor & Restructure

This task is to restructure the projects to separate the client from server. Refactor code for performance and extensibility.

Work without a serializer

Hey. I scanned the code, and I liked it. But I can not find the opportunity to work without a serializer with byte array. Please add this low-level function.

Support multiple RegisterTypes calls on one IBuilder instance

Currently the second RegisterTypes call overrides the previous call as it's saved as an action in the builder.

new ServerBuilder()
    .RegisterTypes(serviceCollection =>
    {
        // Never called
    })
    .RegisterTypes(serviceCollection =>
    {
        // Called
    })

Would be nice if it was possible to call it multiple times or that it alerted that it is already set.

Encryption

I see that encryption is on your road map -- and it's a feature I desperately want in a library like this.

I'm tempted to try and implement it myself in a fork, but I'd likely use something like Inferno. How are you planning to add encryption?

I was looking at the code and I figured it would be fairly easy to register some packet handlers for passing public keys between client/server and then encrypting/decrypting just before serialization/deserialization.

Not working with Unity :(

Hi,

I spent the whole day trying to make this project work with Unity but unfortunately I still cannot import the dll without errors.
I tried many different things and it seems like the necessary dependencies are not included in the build.
Here is the kind of errors I am getting when importing the dll of Networker:

Unable to resolve reference 'Microsoft.Extensions.Logging.Abstractions'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
Unable to resolve reference 'Microsoft.Extensions.Configuration.Abstractions'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
Unable to resolve reference 'Microsoft.Extensions.Logging'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
Unable to resolve reference 'Microsoft.Extensions.DependencyInjection.Abstractions'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
Unable to resolve reference 'Microsoft.Extensions.DependencyInjection'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
Unable to resolve reference 'Microsoft.Extensions.Options.ConfigurationExtensions'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.

Any idea what I am doing wrong or how to fix it?

Thank you,
Etienne

Packet Handler Decorators

What do you think about adding built-in support for Packet Handler Decorators?

We could use an Attribute-based means of assigning Decorators to Packet Handlers and wire them up at startup.

This blog talks about the Command Handler Pattern and has a section about enhancing the pattern with Decorators:

https://blogs.cuttingedge.it/steven/posts/2011/meanwhile-on-the-command-side-of-my-architecture/

The article provides these use case examples:

  • Checking the authorization of the current user before commands get executed
  • Validating commands before commands get executed
  • Measuring the duration of executing commands
  • Logging and audit trailing
  • Executing commands in the background
  • Queuing commands to be processed in a different process

Here's an example of how you might define custom Decorators for a Handler:

[Decorate(
typeof(LoggingHandlerDecorator),
typeof(AuthorizationHandlerDecorator),
typeof(BackgroundJobHandlerDecorator)]
public class SomePacketHandler : PacketHandlerBase<SomePacket>
{
    ....
}

Having a way to define global or module Decorators could prevent having to add the Decorate attribute to so many Handler classes.

Here's an example of the sort of benefits that Decorators can provide, especially when used with helper Attributes:

[Authorization(30)] // User must have authorization level of 30 for this to succeed
public override Task Process(SomePacket packet, IPacketContext context)
{
    ...
}

For this example, the AuthorizationHandlerDecorator.Process method might look something like this:

public override async Task Process(SomePacket packet, IPacketContext context)
{
    int userAccessLevel = 0; // Get user access level from service
    // Gets from the method's Authorization Attribute
    int requiredAccessLevel = GetRequiredAccessLevel(packet);
    if (userAccessLevel >= requiredAccessLevel) 
    {
        await DecoratedHandler.Process(packet, context);
    }
}

Thoughts?

How to use with unity3d?

Hello Mark.

I look for a tcp&udp library for my unity project for a while and i finally find your project.

i have try add the source code to the a new project but it tell the error like the issue(#43)
i also see your blob in your site .but it seems only not to tell how to do it with unity now yet.

Could you please provide a simple unity client project using with the networker source code example in your github repo.

thank you very much. waiting for your reply.

Errors with unity

Hello, i try to use Networker with unity but there are errors:

Error messages

I followed the #43 instructions (Compile Networker.dll to 4.7.2, set unity in .net 4.7.* and put it in a Plugins folder)

In my plugin folder there is Networker.dll in 4.7.2 version and Microsoft.Extensions.Logging.

I have tried to put the assemblies files which causes the problem in it (With the 4.7.2 compilation and without) but it didn't change anything.

Is it possible to make a simple example of a unity project ? Or to upload all the dlls in the good version ?

Thank you

License Considerations

Hey, love the library! One issue however is the library is licensed under GPL v3 which would require all applications/games using it to also be GPL and open source. Is switching to a separate license such as MIT possible?

ServerPacketProcessor处理无长度数据包时陷入循环

var packetSize = packetSerialiser.CanReadLength
? BitConverter.ToInt32(buffer, currentPosition)
: 0;
//包长度后续没赋值,在不能读取长度的业务中陷入循环,如果数据包没有长度说明,则使用整包的长度
var packetSize = packetSerialiser.CanReadLength
? BitConverter.ToInt32(buffer, currentPosition)
: length;

Connect via TCP and UDP and also multiple listeners?

Hello there,
I was wondering if a client is able to connect via both TCP and UDP at the same time allowing you to determine which message types you would like to send over each connection? Also, is it possible to have multiple listeners setup on the server side for more than one port? I wanted the interconnecting servers to connect to one port and clients to connect on another and the messages get handled differently based on what port the connection came in on.

Thanks!

udp数据传输长度为0

  • udp数据传输长度为0
  1. 在IServerPacketProcessor中声明如下:
void ProcessUdpFromBuffer(EndPoint sender, byte[] buffer, int offset = 0, int length = 0);
  1. 在UdpClientListener中未指定数据长度
 private async Task Process(EndPoint endPoint, byte[] buffer)
        {
           // serverPacketProcessor.ProcessUdpFromBuffer(endPoint, buffer);
            serverPacketProcessor.ProcessUdpFromBuffer(endPoint, buffer,0,buffer.Length);
            endPointPool.Push(endPoint);
        }

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.