Skip to content

Instantly share code, notes, and snippets.

@prodigga
Last active November 19, 2023 10:00
Show Gist options
  • Save prodigga/861d72075f9f8abde5fc7b9744a1f4eb to your computer and use it in GitHub Desktop.
Save prodigga/861d72075f9f8abde5fc7b9744a1f4eb to your computer and use it in GitHub Desktop.
SSE's (Server-Sent Events) Download Handler

Whats this?

This is a custom UnityWebRequest Download Handler to support SSE's (Server-Sent Events) in Unity!

How to use it

Simply inhert SseDownloadHandlerBase and supply your own logic (Deserialise incoming lines, expose events, etc).

Then set the download handler to be an instance of your class.

webRequest.downloadHandler = new LogSseExampleDownloadHandler();

Examples

public class LogSseExampleDownloadHandler : SseDownloadHandlerBase
{
    public LogSseExampleDownloadHandler() : base(new byte[1024]) { }

    protected override void OnNewLineReceived(string line)
    {
        Debug.Log(line);
    }
}

public class LogSseWithPooledBufferExampleDownloadHandler : SseDownloadHandlerBase
{
    private byte[] _pooledBuffer;

    public LogSseWithPooledBufferExampleDownloadHandler Create()
    {
        var buffer = ArrayPool<byte>.Shared.Rent(1024);
        return new LogSseWithPooledBufferExampleDownloadHandler(buffer);
    }

    private LogSseWithPooledBufferExampleDownloadHandler(byte[] buffer) : base(buffer)
    {
        _pooledBuffer = buffer;
    }

    protected override void OnNewLineReceived(string line)
    {
        Debug.Log(line);
    }

    public override void Dispose()
    {
        base.Dispose();
        ArrayPool<byte>.Shared.Return(_pooledBuffer);
    }
}
using System.Buffers;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
public abstract class SseDownloadHandlerBase : DownloadHandlerScript
{
private readonly StringBuilder _currentLine = new();
protected SseDownloadHandlerBase(byte[] buffer) : base(buffer) { }
protected abstract void OnNewLineReceived(string line);
protected override bool ReceiveData(byte[] data, int dataLength)
{
for (var i = 0; i < dataLength; i++)
{
var b = data[i];
if (b == '\n')
{
OnNewLineReceived(_currentLine.ToString());
_currentLine.Clear();
}
else
{
_currentLine.Append((char) b);
}
}
return true;
}
protected override void CompleteContent()
{
if(_currentLine.Length > 0)
OnNewLineReceived(_currentLine.ToString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment