{"id":13764438,"url":"https://github.com/SAFE-Stack/SAFE-Chat","last_synced_at":"2025-05-10T19:31:06.286Z","repository":{"id":28099307,"uuid":"113073553","full_name":"SAFE-Stack/SAFE-Chat","owner":"SAFE-Stack","description":"IRC-style chat demo featuring full-stack F#, Akka.Streams, Akkling, Fable, Elmish, Websockets and .NET Core","archived":true,"fork":false,"pushed_at":"2024-09-06T13:26:01.000Z","size":13784,"stargazers_count":175,"open_issues_count":0,"forks_count":25,"subscribers_count":8,"default_branch":"dev","last_synced_at":"2025-05-08T15:43:07.282Z","etag":null,"topics":["akka","akka-streams","fable","fsharp","netcore","netcore20","safe-stack","suave","websocket"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SAFE-Stack.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-12-04T17:30:44.000Z","updated_at":"2024-12-28T04:01:25.000Z","dependencies_parsed_at":"2024-08-03T16:03:31.186Z","dependency_job_id":"ef261b6b-db0a-4fd6-bdb7-cadb2ed9e918","html_url":"https://github.com/SAFE-Stack/SAFE-Chat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAFE-Stack%2FSAFE-Chat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAFE-Stack%2FSAFE-Chat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAFE-Stack%2FSAFE-Chat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAFE-Stack%2FSAFE-Chat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SAFE-Stack","download_url":"https://codeload.github.com/SAFE-Stack/SAFE-Chat/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253470701,"owners_count":21913717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["akka","akka-streams","fable","fsharp","netcore","netcore20","safe-stack","suave","websocket"],"created_at":"2024-08-03T16:00:20.601Z","updated_at":"2025-05-10T19:31:06.246Z","avatar_url":"https://github.com/SAFE-Stack.png","language":"F#","funding_links":[],"categories":["Examples"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/AndrewEgorov/SAFE-Chat.svg?branch=dev)](https://travis-ci.org/AndrewEgorov/SAFE-Chat)\n\n# F#chat\n\nSample chat application built with netcore, F#, Akka.net and Fable.\n\n![Harvest chat](docs/FsChat-login.gif \"Channel view\")\n\n## Requirements\n\n* [dotnet SDK](https://www.microsoft.com/net/download/core) 2.0.0 or higher\n* [.NET Framework 4.6.1 Developer Pack](https://www.microsoft.com/en-us/download/details.aspx?id=49978) to run e2e tests\n* [node.js](https://nodejs.org) 4.8.2 or higher\n* yarn (`npm i yarn -g`)\n* npm5: JS package manager\n\n## Building and running the app\n\n* restore dependencies and build application: `fake build`\n* run the application: `fake build -- start`\n\nMore commands:\n\n* `fake build -- clean build`\n* `fake build -- restore`\n* `fake build -- build` -- just build, no restore\n\nAlternatively follow the instruction below:\n\n* **change current folder to `src/Client` folder**: `cd src/Client`\n* Install JS dependencies: `yarn`\n* Build client bundle: `yarn build`\n* **chdir to `src/Server` folder**: `cd ..\\Server`\n* Install F# dependencies: `dotnet restore`\n* Run the server: `dotnet run`\n* Head your browser to `http://localhost:8083/`\n\n## Developing the app\n\n* Start the server by starting `dotnet run` in `src/Server` folder\n* Navigate to `src/Client` folder\n* Start Fable daemon and [Webpack](https://webpack.js.org/) dev server: `yarn start`\n* In your browser, open: http://localhost:8080/\n* Enjoy HMR (hotload module reload) experience\n\n## Running integration (e2e) tests\n\nE2e tests are based on canopy and webdriver so currently I know it runs on Windows. I have no idea how to run in non-windows environment.\n\n* run the tests: `fake build -- test`\n* stop script by typing `q` then pressing `Enter`\n\nor follow these steps:\n\n* start the server\n* **Move to `test/e2e` folder**: `cd test\\e2e`\n* run the tests: `dotnet run`\n\n\u003e Tests should be run on clean server, but after server became persistent this condition is usually not met (consider cleaning the src/Server/CHAT_DATA folder ny hands).\n\n## Implementation overview\n\n### Authentication\n\nFsChat supports both *permanent* users, authorized via goodle or github account, and *anonymous* ones, those who provide only nickname.\n\nIn order to support the google/fb authentication scenario, fill in the client/secret in the CHAT_DATA/suave.oauth.config file. In case you do not see this file, run the server once and the file will be created automatically.\n\n### Akka streams\n\nFsChat backend is based on Akka.Streams. The entry point is a `GroupChatFlow` module which implements the actor, serving group chat.\n\n`UserSessionFlow` defines the flows for user and control messages, brings everything together and exposes flow for user session.\n\n`AboutFlow` is an example of implementing channel with specific purpose, other than chatting\n\n`ChatServer` is an actor which purpose is to keep the channel list. It's responsible for creating/dropping the channels.\n\n`UserStore` is an actor which purpose is to know all users logged in. It supposed to be made persistent but it does not work for some reason (I created issue).\n\n`SocketFlow` implements a flow decorating the server-side web socket.\n\n### Akkling\n\nAkkling is an unofficial Akka.NET API for F#. It's not just wrapper around Akka.NET API, but introduces some cool concepts such as Effects, typed actors and many more.\n\n### Fable, Elmish\n\nClient is written on F# with the help of Fable and Elmish (library?, framework?). Fable is absolutely mature technology, Elmish is just great.\n\n### Communication protocol\n\nAfter client is authenticated all communication between client and server is carried via WebSockets. The protocol is defined in `src/Shared/ChatProtocol.fs` file which is shared between client and server projects.\n\n### Persistence\n\nServer implementation demonstrates using Akka Persistance to restore server state after restart. It's based on event sourcing.\nHowever the server destroys the channels when all users are gone. So all channels created by users are non-permanent and will unlikely be restored after restart.\n\n## References\n\n* [paket and dotnet cli](https://fsprojects.github.io/Paket/paket-and-dotnet-cli.html)\n* [Akkling Wiki](https://github.com/Horusiath/Akkling/wiki)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSAFE-Stack%2FSAFE-Chat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSAFE-Stack%2FSAFE-Chat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSAFE-Stack%2FSAFE-Chat/lists"}