A desktop instant messenger built for the internal communication needs of a municipal heating utility (ТОВ «Рівнетеплоенерго», Rivne, Ukraine). Employees exchange messages and work files — reports, spreadsheets, invoices — without those files leaving the company network through a third-party service.
This was my diploma project for a Software Engineering qualification, built and defended in 2019. It is archived here as-is, with the original architecture intact. See Known limitations for an honest assessment of what I would do differently today.
- Group chats with an owner/administrator and a participant list
- File attachments — upload and download over a streamed WCF channel, so transfer size is not bounded by the SOAP message buffer
- User directory — search colleagues by login, first name, or surname; view their contact card
- Profile management — edit name, email, phone; change password
- Live updates — the chat list and open conversation refresh from the server continuously
- Runtime theming — full Material Design palette switcher with light/dark modes
| Navigation drawer | Theme picker |
|---|---|
![]() |
![]() |
Three tiers, with a SOAP service boundary between client and data:
WPF client ──SOAP/HTTP──> WCF service ──EF6 Code First──> SQL Server
(Client) (Messeger) (LocalDB by default)
Client/— WPF desktop app (Material Design in XAML, MahApps.Metro). A generated WCF proxy inConnected Services/Server/handles all server calls. A background thread polls for new messages and chats.Messeger/— WCF service exposing 22 operations overbasicHttpBinding, plus the EF6 Code First model. Two bindings are in play: a buffered one for normal calls, and a streamed one for file transfer.- Database — created automatically on first run by the EF initializer in
Custom.cs.
Entities: a User is projected into role tables (Administrator, Participant, Sender,
Receiver), each linking to Chat and Message. Files are stored on disk under a
per-chat GUID folder, with only the path persisted.
| Language | C# 7.3, .NET Framework 4.8 |
| Client | WPF, Material Design in XAML 2.5, MahApps.Metro 1.6 |
| Service | WCF (basicHttpBinding, buffered + streamed) |
| Data | Entity Framework 6.2 Code First, SQL Server / LocalDB |
| Host | IIS Express |
The stack reflects its 2019 coursework context — WCF and .NET Framework were the required
technologies. .NET Core 3.0, which brought WPF cross-platform, was still in preview at
the time, and WCF server-side has never been ported to it.
Requirements: Visual Studio 2022 (any edition) with the .NET desktop development and ASP.NET and web development workloads. LocalDB is included with both.
git clone https://github.com/Dimitriuses/Messeger.git
cd Messeger
- Open
Messeger.sln. NuGet restores on first build — no manual step. - Set both projects to start: right-click the solution → Set Startup Projects →
Multiple startup projects → set
MessegerandClientto Start. - Press F5.
The service comes up on http://localhost:63716/Service1.svc, which is what
Client/App.config expects. The database is created on first run.
To point at a real SQL Server instead of LocalDB, edit the Meseger connection string in
Messeger/Web.config.
Register a user from the client with the profile button in the left drawer → Реєстрація.
The user interface is Ukrainian throughout, as it was written for a Ukrainian workplace. I have kept it that way rather than retrofitting a translation — it is part of what the project actually was. The code, this README, and all identifiers are in English.
docs/README.md captions every image in English and gives a reading key
for the Ukrainian labels in the architecture diagram.
This is a 2019 student project, and it has the flaws of one. I would not ship it as-is, and the honest list matters more than a polished one:
Security
- Passwords are hashed with unsalted MD5. Should be PBKDF2, bcrypt, or Argon2 with a per-user salt.
- There is no session concept. The login and password hash are sent as parameters on
every single service call, and the binding uses
security mode="None"— so credentials cross the wire in plaintext on every request. A token issued once at login, over HTTPS, is the fix. includeExceptionDetailInFaultsanddirectoryBrowseare left enabled inWeb.config. Fine for local debugging, wrong for anything deployed.
Correctness and design
- The client polls. There is no push channel, so it asks the server on a one-second interval. WCF duplex callbacks are the right answer and were not used. Worse, the service re-authenticates inside each operation, so a single poll pass costs roughly a dozen database round trips.
- Sender names are not part of the message payload, so the client has to resolve
senderId -> loginseparately. It caches the mapping, which keeps this off the hot path, but the DTO should simply carry the login. chatIdin the service API is a positional index into the caller's chat list, not a stable identifier. If the list changes between calls, the wrong chat can be addressed.MessageandFileshare a primary key as an implicit 1:1 association, soDownloadFilefinds a file by message id. It works, but the coupling is invisible in the model.- Several
catchblocks swallow exceptions silently.
Naming
- Several identifiers carry spelling mistakes from 2019 —
Meseger(theDbContext),Loger,Reciver,SingIN,Registr, andProfilerfor what is actually a profile dialog. They are deliberately left alone:Logerand the DTOs are part of the WCF data contract and appear in the generated client proxy, so renaming them means regenerating the service reference. Not worth the churn on an archived project.
Testing
- There are no automated tests. Verification was manual, against a written test plan.
Client/ WPF desktop client
Connected Services/Server/ generated WCF proxy
Messeger/ WCF service + EF6 model
Model/ entities
DTO/ data transfer objects
docs/ screenshots and diagrams (see docs/README.md)



