Real-time Web mit SharePoint (SignalR) Update

In Real-time Web mit SharePoint SignalR Update, aktualisieren wir die SimpleChat Lösung und erweitern diese.

Real-time Web mit SharePoint (SignalR) Update

Bei dem Ursprünglichen Blog Post (hier) wurde bereits auf SignalR und die Verwendung in SharePoint eingegangen. Um den Post nicht all zu trocken zu gestalten, wurden fertig entwickelte SharePoint Lösungen vorgestellt. Einer davon ist die SimpleChat Lösung.

Bild: SimpleChat in der Ursprungs-Version

Die SimpleChat Anwendung sollte quasi das SignalR "Hello World" Beispiel (... für SignalR ist eine Chat-Anwendung wie das "Hello World" in jeder Programmiersprache :-)) innerhalb von SharePoint demonstrieren. Wie auf dem Bild zu sehen, funktionierte das Ganze auch mehr oder weniger gut zusammen... Ich habe (zum Glück) sehr penible Kollegen (siehe Bild :)), obwohl das ein Test zum erstellen eines Screenshots für den Blog-Post war, kamen im Chat bereits die ersten Change Requests oder Bug-Meldungen :)

Fassen wir mal zusammen...

Bugs

  • B01: Beim Tippen einer Nachricht werden alle bereits versendeten Nachrichten angezeigt, die Autovervollständigung soll nicht greifen.
  • B02: Die Uhrzeiten der Nachrichten werden nicht einheitlich angezeigt.

Changes

  • CR01: Beim klicken von Enter soll die Nachricht versendet werden.
  • CR02: Beim neuladen oder ersten Anmelden wird die Chat-Historie nicht angezeigt. Die Historie soll jedoch bei den genannten Interaktionen angezeigt werden.

WTF?

  • Wer zum Teufel sind "White Rabbit" und "jkhjkhjkh"? :)

Dann fangen wir mal an...

Bug B01 (Input History):

Zuerst beseitigen wir den ersten Bug "Beim Tippen einer Nachricht werden alle bereits versendeten Nachrichten angezeigt, die Autovervollständigung soll nicht greifen.". Die Lösung ist hier ganz easy, das Input Element muss um das "autocomplete" Attribut mit dem Wert "off" erweitert werden.

Bild: Automatische Vervollständigung wird abgeschaltet

... damit ist der erste Bug Geschichte :)

Bug B02 (unterschiedliche Uhrzeiten)

Achja, das ewige Problem mit den Zeitzonen, der angezeigten Zeit und Zeit-Berechnung in JavaScript. Was ist hier das Problem? Das Gebietsschema dieses Webs steht auf "Deutsch" was folglich eine 24 Stunden Anzeige bedingt.

Bild: Landes-/Regionaleinstellungen

Bis jetzt wurde beim senden das Zeitformat des Clients (Browser) berücksichtigt, das Web ist Deutsch und die meisten Kollegen verwenden anscheinend ein deutsches Betriebssystem mit deutschem Gebietsschema im Browser. Falls jemand mit anderen Region-Einstellungen unseren Chat besucht, wird das Zeitformat von seinem Browser verwendet und dem SignalR HUB übermittelt. Alle anderen Teilnehmer bekommen diesen Eintrag mit dieser unterschiedlichen Formatierung angezeigt. Um dieses Problem zu beheben müssen wir uns auf ein Format einigen. Hier fängt das Dilemma an, wo stelle ich dieses Format fest? Theoretisch stehen uns auf jeder Page, die von der MasterPage erbt, die Informationen (nicht alle natürlich) für die aktuelle Einstellung des Web und Benutzer bereit.

Bild: der Inhalt des _spPageContextInfo Objekts

So, was kann man jetzt mit diesen Informationen anfangen? Vieles, wir können mit Standard SharePoint mittlen (z.B. mit Verwendung von SP.Utilities.Utility.formatDateTime() oder wir schreiben die Formatierungsvorlage Server-Seitig raus, etc.) und mit viel Arbeit eine einheitliche Anzeige für alle schaffen ... All diese Überlegungen sind zum einen sehr Kopfzerbrechend (z.B. Offset Berechnungen von Benutzern in anderen Zeitzonen) und zum anderen brauchen wir das auch nicht. Wieso? Ganz einfach, wir speichern keine Informationen in SharePoint Elementen ab, deswegen müssen wir uns in diesem Fall darüber keinen Kopf machen. Die einfachste Lösung hier ist, beim Aufruf der "Send" Hub Methode anstatt der lokalen Uhrzeit das Date Objekt als ISO String zu übermitteln und beim Aufruf der "broadcastMessage" die Formatierung zu übernehmen. Dadurch sieht bei jedem Benutzer die Zeitanzeige einheitlich aus.

B02 erledigt :)

CR01 (Beim klicken von Enter soll die Nachricht versendet werden)

Aktuell wird beim klicken auf Enter die Seite neu geladen. Das sollen wir nun abfangen und die eingegebene Nachricht der gesamten Masse im Chat bereitstellen. Das ist ziemlich einfach zu bewerkstelligen. Wir müssen lediglich einen Event auf dem Input Element registrieren. In diesem Fall binden wir unseren Code an das key down Event. Damit wird unser Code auf jeden Tastendruck innerhalb des Input Elements reagieren und überprüfen ob die Enter Taste gedrückt wurde. Wenn dem der Fall sein sollte, wird unser "onClick" Event am submit button gefeuert und die Nachricht wird versendet.

Bild: Wir fangen den Key Down Event ab

Dafür können wir jQuery verwenden und den "keyDown" Event abfangen. Registriert wird der Event direkt am Input Element. Die Enter-Taste hat die 13 als Char-Code.

CR01: done...

Fast fertig...

... nicht wirklich. Jetzt kommt der spannende Teil. Es liegen vor uns noch der Change mit dem Chat-Verlauf (CR02) und die Punkte unterhalb der anderen Rubrik (WTF).

Wer ist White Rabbit? White Rabbit ist ein Geist, wir haben keinen Mitarbeiter mit Vornamen White und Nachnamen Rabbit (was an sich Toll wäre). Damals hatte ich die Vision für ein Update Blog Post, woraufhin ich mich auf den SignalR Host verbunden habe. Wir haben eine index.html in dem SignalRTest Projekt. Beim direkten Aufruf der IIS Instanz wird diese angezeigt.

Bild: SignalR Host

Beim Aufruf poppt ein Pop-Up Fenster auf wo ein Name eingegeben werden muss (z.B. "White Rabbit"), an dieser Stelle findet keine Validierung statt. In der ersten Version fand keine Gruppierung der Chats statt. Mit anderen Worten, unser WebPart hätte auf 2,3,4 oder n Seiten eingesetzt werden können, und jeder WebPart hätte alle Nachrichten aus allen Chats angezeigt, inkl. derer die z.B. auf der besagten Seite eingegeben wurden. Dadurch kamen die Nachrichten von "White Rabbit" und "jkhjkhjkh" zu Stande. Um es genauer zu titulieren, ich habe geschummelt :-) ... Jetzt stellen wir uns mal folgenden Fall vor.

Die Geschäftsführung hat eine eigene SharePoint Teamsite. Innerhalb dieser Team-Site gibt es eine Seite, wo der SimpleChat WebPart eingesetzt wird. Innerhalb der SharePoint Umgebung gibt es eine weitere Team-Site für alle Mitarbeiter, auch innerhalb dieser SiteCollection wird der Chat verwendet.

Die Geschäftsführung verwendet den Chat gelegentlich für Absprachen etc., es werden zum Teil auch Unternehmens-Kritische Themen besprochen. In der aktuellen Version könnte ein einfacher Benutzer ohne tiefer gehende IT-Kenntnisse diese Konversation mitverfolgen.

Anforderungen & Bugs (die zweite bzw. Update)

Mit der letzten Erkenntnis hat sich ein neuer CR heraus kristallisiert, den so außer mir niemand auf dem Schirm hatte. An sich ein guter Zeitpunkt um die Anforderung von oben aufzuräumen und zu ergänzen.

Bugs

  • B01: Beim Tippen einer Nachricht werden alle bereits versendeten Nachrichten angezeigt, die Autovervollständigung soll nicht greifen. (erledigt)
  • B02: Die Uhrzeiten der Nachrichten werden nicht einheitlich angezeigt. (erledigt)

Changes

  • CR01: Beim klicken von Enter soll die Nachricht versendet werden. (erledigt)
  • CR02: Beim neuladen oder ersten Anmelden wird die Chat-Historie nicht angezeigt. Die Historie soll jedoch bei den genannten Interaktionen angezeigt werden.
  • CR03: Aus Sicherheitsaspekten und der Übersicht halber, sollen die Nachrichten nur in dem jeweiligen Chat angezeigt werden, wo die Nachricht auch erstellt wird.

CR02 Caching für Chat-Historie / CR03 Chat-Gruppen

In diesem Beispiel habe ich ein In-Memory Cache eingebaut, sprich die Historie lebt solange bis zum nächsten IIS Pool Recycle oder Server-Neustart. Für eine Persistente Lösung, könnte an dieser Stelle auf eine Form von Datenbank gesetzt werden.

Das Caching ist im HUB implementiert und liefert bei einem "Join" die History - sofern vorhanden - dem User zurück.

Beim Anmelden - bzw. Erstellen des Channels - wird nun nach der WebPartID unterschieden. Sprich jeder WebPart ist eine eigene Chat-Gruppe.

Falls jemand die Unterschiede einsehen möchte, kann er dies bei den Commits tun.

Commit#1 (erstes Update)

Commit#2 (zweites Update)

Zu guter letzt...

Leider muss ich aus zeitlichen Gründen diesen Beitrag an dieser Stelle beenden. Im Letzten Punkt bin ich auf die Änderungen nicht im Detail eingegangen. Diese können jedoch über die Commits eingesehen werden.

Dieser Beitrag war als Ergänzung zu dem ersten Beitrag gedacht, daher hat dieses Thema nun ein vernünftiges Ende gefunden. mit dieser Lösung haben wir nun ein Microsoft Teams für Arme - ohne die coolen Features :) - gebaut, die SimpleChat Anwendung könnte sogar mit ein Paar Handgriffen im (kleinen) Unternehmen eingesetzt werden.