Exemplo n.º 1
0
        static async Task Main(string[] args)
        {
            var mochi = new Mochi.HTTPServer();

            mochi.Get("/", async ctx =>
            {
                await ctx.Response.WriteAsync(Template, ctx.CancellationToken);
            });

            mochi.Get("/echo", async ctx =>
            {
                ctx.Response.SetContentType(ContentTypes.TextPlane);
                await ctx.Response.WriteStatusCodeAsync(200, ctx.CancellationToken);
                foreach (var pair in ctx.Reqeust.Headers)
                {
                    await ctx.Response.WriteAsync($"{pair.Key}: {pair.Value}\n", ctx.CancellationToken);
                }
            });

            mochi.Get("/form", async ctx =>
            {
                await ctx.Response.WriteAsync(@"<body>
    <form action=""/post"" method=""post"">
        <div><input name=""text""></div>
        <div><input name=""text""></div>
        <button>submit</button>
    </form>
</body>", ctx.CancellationToken);
            });

            mochi.Post("/post", async ctx =>
            {
                ctx.Response.SetContentType(ContentTypes.TextPlane);
                await ctx.Response.WriteStatusCodeAsync(200, ctx.CancellationToken);
                foreach (var(name, values) in ctx.Reqeust.Form.EnumerateAllValues())
                {
                    await ctx.Response.WriteAsync($"{name}: {string.Join(',', values)}\n", ctx.CancellationToken);
                }
            });

            mochi.Get("/*", async ctx =>
            {
                await ctx.Response.WriteAsync(FallbackTemplate, ctx.CancellationToken);
            });

            await mochi.StartServeAsync(new IPEndPoint(IPAddress.Loopback, 8080), CancellationToken.None);
        }
Exemplo n.º 2
0
        static async Task Main(string[] args)
        {
            var mochi = new Mochi.HTTPServer();

            var signaler = new Mochi.Async.Signaler();
            var fiber    = new Mochi.Async.Fiber();
            var messages = new List <string>();
            var clients  = new List <Client>();

            Func <Mochi.Context, Task> RenderFileHandler(string path)
            {
                return(async ctx =>
                {
                    var ext = System.IO.Path.GetExtension(path).ToLower();
                    switch (ext)
                    {
                    case ".htm":
                    case ".html":
                        ctx.Response.SetContentType(ContentTypes.TextHtml);
                        break;

                    case ".js":
                        ctx.Response.SetContentType(ContentTypes.ApplicationJavaScript);
                        break;

                    default:
                        break;
                    }

                    // every time read file from disk(for debug.)
                    var data = await System.IO.File.ReadAllBytesAsync(path, ctx.CancellationToken);

                    await ctx.Response.WriteAsync(data, ctx.CancellationToken);
                });
            }

            // render static files.
            mochi.Get("/", RenderFileHandler("./public/index.html"));
            mochi.Get("/main.js", RenderFileHandler("./public/main.js"));

            mochi.Post("/post", async ctx =>
            {
                var name = ctx.Reqeust.Form.GetValue("name");
                var text = ctx.Reqeust.Form.GetValue("text");
                if (string.IsNullOrEmpty(name) || name.Contains(',') || name.Contains(':'))
                {
                    await ctx.Response.WriteStatusCodeAsync(400, ctx.CancellationToken);
                    await ctx.Response.WriteAsync("Bad Request", ctx.CancellationToken);
                    return;
                }

                await fiber;
                messages.Add($"{name},{text}");
                signaler.Signal();

                await ctx.Response.WriteAsync("OK", ctx.CancellationToken);
            });

            mochi.Get("/sse", async ctx =>
            {
                ctx.Response.SetHeader("Access-Control-Allow-Origin", "*");
                ctx.Response.SetContentType("text/event-stream; charset=utf-8");

                var client = new Client(new Queue <string>(), new Mochi.Async.Signaler());

                await fiber;
                clients.Add(client);

                try
                {
                    while (true)
                    {
                        await client.Signaler.WaitSignalAsync(ctx.CancellationToken);

                        while (true)
                        {
                            await fiber;
                            if (client.Queue.Count == 0)
                            {
                                break;
                            }
                            var text = client.Queue.Dequeue();
                            await ctx.Response.WriteAsync($"data: {text}\r\n\r\n", ctx.CancellationToken);
                            await ctx.Response.FlushAsync(ctx.CancellationToken);
                        }
                    }
                }
                finally
                {
                    await fiber;
                    clients.Remove(client);
                }
            });


            _ = Task.Run(async() =>
            {
                while (true)
                {
                    await signaler.WaitSignalAsync(default(CancellationToken));

                    while (true)
                    {
                        await fiber;
                        if (messages.Count == 0)
                        {
                            break;
                        }

                        foreach (var message in messages)
                        {
                            foreach (var client in clients)
                            {
                                client.Queue.Enqueue(message);
                            }
                        }

                        foreach (var client in clients)
                        {
                            client.Signaler.Signal();
                        }
                        messages.Clear();
                    }
                }
            });

            await mochi.StartServeAsync(new IPEndPoint(IPAddress.Loopback, 8080), CancellationToken.None);
        }