Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

supersocket 2.0 with unity3d 2022.3 #691

Open
jessienms opened this issue Dec 15, 2023 · 7 comments
Open

supersocket 2.0 with unity3d 2022.3 #691

jessienms opened this issue Dec 15, 2023 · 7 comments
Assignees
Labels
2.0 SuperSocket 2.0 bug u3d

Comments

@jessienms
Copy link

supersocket 2.0.0
unity3d 2022.3.13f1

I am currently building a server using SuperSocket and creating a game project in Unity3d to implement a feature that connects and exchanges packets. When I run the same code in a general .NET console project, the packet reception works without any problems, but when I run the same code in Unity3D, send works but recv does not.

When debugging in Unity3d, the PipeChannel.ReadPipeAsync task is executed, but when PipeReader.ReadAsync is finished and pipeChannel.ReaderBuffer is called below, the state of the buffer is all filled with 0, so a protocol error occurs.

Could you give me some advice on this problem?

@kerryjiang
Copy link
Owner

It looks like network protocol issue. Which kind of protocol do you use?

@penspanic
Copy link

I'm facing this issue too.
Versions tested - 2.0.0-beta.18(nuget), 2.0.0-beta.20.440(myget)

Could anyone give me some advice?

@kerryjiang
Copy link
Owner

kerryjiang commented Apr 14, 2024

Could you point the code you debugged?

@wangruoyi1996
Copy link

I solved it.
`
public class MyTcpPipeConnection : TcpPipeConnection
{

private System.Net.Sockets.Socket m_Socket;

public MyTcpPipeConnection(System.Net.Sockets.Socket socket, ConnectionOptions options) : base(socket, options)
{
    m_Socket = socket;
}

protected override async ValueTask<int> FillPipeWithDataAsync(Memory<byte> memory, CancellationToken cancellationToken)
{
    return await MyReceiveAsync(m_Socket, memory, SocketFlags.None, cancellationToken);
}

private async ValueTask<int> MyReceiveAsync(System.Net.Sockets.Socket socket, Memory<byte> memory, SocketFlags socketFlags, CancellationToken cancellationToken)
{
    MemoryMarshal.TryGetArray<byte>(memory, out ArraySegment<byte> buffer);
    return await socket.ReceiveAsync(buffer, socketFlags).ConfigureAwait(false);
}

}

public class MyTcpConnectionFactory : TcpConnectionFactory
{
public MyTcpConnectionFactory(ListenOptions listenOptions, ConnectionOptions connectionOptions, Action<System.Net.Sockets.Socket> socketOptionsSetter, IConnectionStreamInitializersFactory connectionStreamInitializersFactory) : base(listenOptions, connectionOptions, socketOptionsSetter, connectionStreamInitializersFactory)
{
}

public override async Task<IConnection> CreateConnection(object connection, CancellationToken cancellationToken)
{
    var socket = connection as System.Net.Sockets.Socket;

    ApplySocketOptions(socket);

    if (ConnectionStreamInitializers is IEnumerable<IConnectionStreamInitializer> connectionStreamInitializers
        && connectionStreamInitializers.Any())
    {
        var stream = default(Stream);

        foreach (var initializer in connectionStreamInitializers)
        {
            stream = await initializer.InitializeAsync(socket, stream, cancellationToken);
        }

        return new StreamPipeConnection(stream, socket.RemoteEndPoint, socket.LocalEndPoint, ConnectionOptions);
    }

    return new MyTcpPipeConnection(socket, ConnectionOptions);
}

}

public class MyConnectionFactoryBuilder : ConnectionFactoryBuilder
{
public MyConnectionFactoryBuilder(SocketOptionsSetter socketOptionsSetter, IConnectionStreamInitializersFactory connectionStreamInitializersFactory) : base(socketOptionsSetter, connectionStreamInitializersFactory)
{
}

public override IConnectionFactory Build(ListenOptions listenOptions, ConnectionOptions connectionOptions)
{
    return new MyTcpConnectionFactory(listenOptions, connectionOptions, SocketOptionsSetter, ConnectionStreamInitializersFactory);
}

}
`
Create the above three scripts, then add server configuration
.ConfigureServices(options => { options.AddSingleton<IConnectionFactoryBuilder, MyConnectionFactoryBuilder>(); })

@kerryjiang kerryjiang self-assigned this Aug 27, 2024
@kerryjiang kerryjiang added bug 2.0 SuperSocket 2.0 u3d labels Aug 27, 2024
@kerryjiang
Copy link
Owner

I will try to understand the problem.

@kerryjiang
Copy link
Owner

@wangruoyi1996 @jessienms I only noticed one difference between @wangruoyi1996 's solution and SuperSocket's code.

The fix

MemoryMarshal.TryGetArray<byte>(memory, out ArraySegment<byte> buffer);

The SuperSocket

MemoryMarshal.TryGetArray(memory, out buffer);

SuperSocket get the generic type argument's type inferring instead of declaring the type directly. It looks like a compiling issue?

@kerryjiang
Copy link
Owner

Pushed a fix according to my guess:
f2e549d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.0 SuperSocket 2.0 bug u3d
Projects
None yet
Development

No branches or pull requests

4 participants