Messaging systeem in webapplicatie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
In navolging van Professionele vs Hobbymatige topics in Devschuur dacht ik om maar eens een topic te starten over de architectuur van het sturen van berichten van user A naar user B via een webapplicatie. Neem bijvoorbeeld het Direct Messaging systeem van React als voorbeeld.

Het hoeft niet bijzonder veel te kunnen, maar je zou kunnen denken aan het volgende:
  1. Een gebruiker A stuurt een bericht (onderwerp + tekst) naar gebruiker B
  2. B ziet "1 ongelezen bericht" en kan deze lezen. Markering van ongelezen > gelezen
  3. B antwoord op bericht (slechts tekst) richting A
  4. A ziet "1 ongelezen bericht" en kan deze lezen. Markering van ongelezen > gelezen
  5. ...
Hoe zou je dit mooi in entiteiten kunnen vangen? Uiteraard heb je een User object en een Message object. Maar het onderwerp van de thread wil je maar één keer kunnen aangeven (de eerste keer). Slechts een object om één keer een onderwerp in op te slaan: is dat wel zo handig?
Aan de andere kant: je wil berichten en reacties wel binnen een thread houden en niet elk bericht als een los berichtje zien.

Nog een vraag: hoe spoor je eigen berichten op (en hoeveel daarvan ongelezen zijn).
SQL:
1
SELECT COUNT(m.id) FROM messages m WHERE m.to = [userId] AND m.read = false


Ik vraag me het af omdat ik een systeem wil bouwen waar het sturen van berichten cruciaal zal zijn. Met een hoop gebruikers en nog veel meer berichten, is het niet te doen om later het systeem om te gooien. Is wat hierboven is geschetst een normale gang van zaken, of zijn er ervaringen met een andere architectuur welke veel flexibeler/performanter/whatever is?

Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Ik zou ook een Thread object introduceren, om daarin de complete conversatie en wat conversatie-specifieke dingen in op te slaan:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class PrivateMessageThread
{
    public IEnumerable<PrivateMessage> Messages
    {
        get;
        set;
    }

    public string Subject
    {
        get;
        private set;
    }
}

Je hebt dus 3 objecten nodig, een User & een PrivateMessage naast de PrivateMessageThread.

[ Voor 11% gewijzigd door AtleX op 23-06-2010 20:00 ]


Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
Volgens mij doen de meeste mail clients threading op basis van een message id en een datum.

Wil je het netjes doen, kun je een parent->child boom gaan bijhouden van berichten en dan recursief terug naar boven lopen. Of bij alle berichten 1 extra veld opslaan met de eerste message ID zodat je met een (inner) join ineens de subject van een bericht op kunt halen. Echter je ontneemt daarmee direct je leden de mogelijkheid om binnen een thread van bericht titel te wijzigen. Daarom doen de meeste het dus op basis van een unieke message ID (UID in mysql)

Of jawel... daar komt ie weer, je gebruikt een noSQL structuur om het systeem te bouwen, een relatief plat message systeem is een van de textbook usecases hiervoor ;)

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Het is zeker een goed idee om ergens een goede identifier mee te geven. Uiteindelijk is het misschien ook het idee om de messages met email te kunnen versturen, maar toch via het systeem. Je stuurt dus mailtjes naar de server die door een (u)id weet op welk mailtje je precies reageert (en desgewenst met email notificatie de ander op de hoogte brengt).

Dat is verder nog wel een grotere uitdaging omdat je de email helemaal moet doorspitten op wat de reactie nu is en wat alle "junk" is die eromheen hangt :*)

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Nu online

MueR

Admin Tweakers Discord

is niet lief

Er zijn nogal wat mogelijkheden voor. Ik heb voor de gein even een database van phpBB3 er bij gepakt om te kijken wat zij doen, aangezien het redelijk dicht bij de direct message functionaliteit in React zit. Daar maakt men gebruik van de volgende structuur (wat veldjes er uit gesloopt):
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE IF NOT EXISTS `phpbb_privmsgs` (
  `msg_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `root_level` mediumint(8) unsigned NOT NULL DEFAULT '0',
  `author_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
  `message_time` int(11) unsigned NOT NULL DEFAULT '0',
  `message_subject` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
  `message_text` mediumtext COLLATE utf8_bin NOT NULL,
  `to_address` text COLLATE utf8_bin NOT NULL,
  `bcc_address` text COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`msg_id`),
  KEY `author_ip` (`author_ip`), KEY `message_time` (`message_time`),
  KEY `author_id` (`author_id`), KEY `root_level` (`root_level`)
)


Hier zitten nog wel wat extra tabellen bij, maar dat zijn voornamelijk flags (zoals unread, replied etc). Root_level in deze is het ID van het eerste bericht in een thread, verder gewoon gesorteerd op time. Ook bieden ze per bericht een subject. Uiteraard is het subject van het eerste bericht leading, de rest wordt alleen weergegeven bij het bericht. Het enige wat ik niet heel handig vind is het gebruik van textfields voor ontvangers, waar entiteiten als u_2 en g_12 voor user en group in (kunnen) staan.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
mithras schreef op woensdag 23 juni 2010 @ 20:14:

Dat is verder nog wel een grotere uitdaging omdat je de email helemaal moet doorspitten op wat de reactie nu is en wat alle "junk" is die eromheen hangt :*)
Dat moet je niet willen doen, en het makkelijkst is het om gewoon een extra property in je mime header te schieten en die weer terug te halen door de mail server heel de mail terug te geven aan je script.

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • Sihaya
  • Registratie: Juni 2001
  • Niet online

Sihaya

Pasfoto:

Wellicht is het ook nog handig om de addressering van een bericht los te zien van de inhoud van het bericht. Dus dat de entiteit bericht een 1:n relatie heeft tot de entiteit addressering (welke weer een 1:1 relatie heeft met entiteit gebruiker).

In de toekomst zou je op deze manier efficient berichten naar meerdere ontvangers kunnen ondersteunen.

signature has expired

Pagina: 1