Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Integrating Node.js

Integrating Node.js

Presentation given at Drupalcamp Austin 2013.

Ryan Oles

June 22, 2013
Tweet

Transcript

  1. HELLO. t h e o l e s c h

    o o l . c o m d . o / u s e r / 1 1 4 0 5 8 t w i t t e r . c o m / r h o _ g i t h u b . c o m / r h 0
  2. NODE.JS Server side javascript Single threaded event loop Code must

    be non blocking Socket.io allows for “real time” client server communication.
  3. 1. Normal Drupal page load. (with auth token) 2. Socket.io

    asks for a connection using the auth token.
  4. 1. Normal Drupal page load. (with auth token) 2. Socket.io

    asks for a connection using the auth token. 3. Node.js sends the auth token to drupal.
  5. 1. Normal Drupal page load. (with auth token) 2. Socket.io

    asks for a connection using the auth token. 3. Node.js sends the auth token to drupal. 4. Drupal sends node a list of channels (and some other information) for that user.
  6. 1. Normal Drupal page load. (with auth token) 2. Socket.io

    asks for a connection using the auth token. 3. Node.js sends the auth token to drupal. 4. Drupal sends node a list of channels for that user. 5. Node.js notifies the client that auth was successful.
  7. SEND A MESSAGE TO ALL USERS. $ s u b

    j e c t = " T o a l l u s e r s : " ; $ b o d y = " H e l l o W o r l d ! " ; n o d e j s _ b r o a d c a s t _ m e s s a g e ( $ s u b j e c t , $ b o d y ) ;
  8. A CLOSER LOOK. n o d e j s .

    m o d u l e f u n c t i o n n o d e j s _ b r o a d c a s t _ m e s s a g e ( $ s u b j e c t , $ b o d y ) { $ m e s s a g e = ( o b j e c t ) a r r a y ( ' b r o a d c a s t ' = > T R U E , ' d a t a ' = > ( o b j e c t ) a r r a y ( ' s u b j e c t ' = > $ s u b j e c t , ' b o d y ' = > $ b o d y , ) , ' c h a n n e l ' = > ' n o d e j s _ n o t i f y ' , ) ; n o d e j s _ e n q u e u e _ m e s s a g e ( $ m e s s a g e ) ; }
  9. h o o k _ n o d e j

    s _ u s e r _ c h a n n e l s ( ) m e s s a g e j s . m o d u l e f u n c t i o n m e s s a g e j s _ n o d e j s _ u s e r _ c h a n n e l s ( $ a u t h _ u s e r ) { $ c h a n n e l s = a r r a y ( ) ; i f ( u s e r _ a c c e s s ( ' r e c e i v e m e s s a g e j s n o t i f i c a t i o n s ' , $ a u t h _ u s e r ) ) { $ c h a n n e l s [ ] = ' m e s s a g e j s _ g e n e r a l ' ; } r e t u r n $ c h a n n e l s ; }
  10. SEND A MESSAGE TO CHANNEL SUBSCRIBERS. m e s s

    a g e j s . m o d u l e f u n c t i o n m e s s a g e j s _ s e n d _ m e s s a g e ( $ b o d y , $ s u b j e c t = ' ' ) { $ n o t i f i c a t i o n = n e w s t d C l a s s ( ) ; $ n o t i f i c a t i o n - > c h a n n e l = ' m e s s a g e j s _ g e n e r a l ' ; $ n o t i f i c a t i o n - > d a t a [ ' s u b j e c t ' ] = $ s u b j e c t ; $ n o t i f i c a t i o n - > d a t a [ ' b o d y ' ] = $ b o d y ; $ n o t i f i c a t i o n - > c a l l b a c k = ' n o d e j s N o t i f y ' ; n o d e j s _ e n q u e u e _ m e s s a g e ( $ n o t i f i c a t i o n ) ; }
  11. h t t p : / / g i t

    h u b . c o m / r h 0 / s w a p i t _ d e m o
  12. h o o k _ n o d e j

    s _ h a n d l e r s _ i n f o ( ) s w a p i t _ d e m o . m o d u l e f u n c t i o n s w a p i t _ d e m o _ n o d e j s _ h a n d l e r s _ i n f o ( ) { r e t u r n a r r a y ( d r u p a l _ g e t _ p a t h ( ' m o d u l e ' , ' s w a p i t _ d e m o ' ) . ' / s w a p i t _ d e m o . c l i e n t . j s ' , ) ; }
  13. BUILD AND SEND THE MESSAGE OBJECT. s w a p

    i t _ d e m o . m o d u l e $ m e s s a g e = n e w s t d C l a s s ( ) ; $ m e s s a g e - > c h a n n e l = ' s w a p i t _ d e m o ' ; $ m e s s a g e - > d a t a [ ' b o d y ' ] = $ u s e r _ m s g ; $ m e s s a g e - > c a l l b a c k = ' s w a p I t ' ; n o d e j s _ s e n d _ m e s s a g e ( $ m e s s a g e ) ;
  14. CLIENT SIDE CALLBACK GETS THE MESSAGE s w a p

    i t _ d e m o . c l i e n t . j s D r u p a l . N o d e j s . c a l l b a c k s . s w a p I t = { / / g r a b t h e m e s s a g e a n d i n j e c t i n t o t h e D O M c a l l b a c k : f u n c t i o n ( m e s s a g e ) { i f ( m e s s a g e . c h a n n e l = = ' s w a p i t _ d e m o ' ) { $ ( ' f o r m # n o d e j s - s e l e c t o r ' ) . h t m l ( m e s s a g e . d a t a . b o d y ) ; } } } ;
  15. h t t p : / / d e m

    o . t h e o l e s c h o o l . c o m / s w a p
  16. SO WHERE DO WE STAND? The nodejs module establishes a

    handy node authentication on Drupal rendered pages. “It handles the Plumbing.” Pushes messages to clients via socket.io. Define custom channels to target message delivery using h o o k _ n o d e j s _ u s e r _ c h a n n e l s ( ) . We can customize client side message handling using h o o k _ n o d e j s _ h a n d l e r s _ i n f o ( ) and writing some client side JS.
  17. SERVER EXTENSIONS THEY LET YOU GET YOUR NODE ON! n

    o d e j s / n o d e j s . s e r v e r . e x t e n s i o n . j s . e x a m p l e
  18. THE CONFIG OBJECT IS HERE TO HELP. c o n

    f i g . p u b l i s h M e s s a g e T o C l i e n t ( ) ; c o n f i g . p u b l i s h M e s s a g e T o C h a n n e l ( ) ; c o n f i g . s e n d M e s s a g e T o B a c k e n d ( ) ; e x p o r t s . s e t u p = f u n c t i o n ( c o n f i g ) { . . . }
  19. CALLBACKS p r o c e s s . o

    n c l i e n t - c o n n e c t i o n c l i e n t - a u t h e n t i c a t e d c l i e n t - m e s s a g e c l i e n t - d i s c o n n e c t
  20. A CLIENT HAS CONNECTED, DO SOMETHING! n o d e

    j s / n o d e j s . s e r v e r . e x t e n s i o n . j s . e x a m p l e p r o c e s s . o n ( ' c l i e n t - c o n n e c t i o n ' , f u n c t i o n ( s e s s i o n I d ) { c o n s o l e . l o g ( ' . . . g o t c o n n e c t i o n e v e n t f o r s e s s i o n ' + s e s s i o n I d ) ; c o n f i g . p u b l i s h M e s s a g e T o C l i e n t ( s e s s i o n I d , { d a t a : { s u b j e c t : ' E x a m p l e e x t e n s i o n ' , b o d y : ' H e l l o , y o u j u s t c o n n e c t e d . ' } } ) ; } )
  21. TALK BACK THROUGH SOCKET.IO D r u p a l

    . N o d e j s . s o c k e t . e m i t ( )
  22. DECIDE WHAT TO SAY. THEN SAY IT n o d

    e _ t o _ d r u p a l . c l i e n t . j s v a r m e s s a g e = { t y p e : ' n o d e T o D r u p a l ' , m e s s a g e B o d y : ' H e l l o f r o m t h e c l i e n t s i d e ! ' } ; $ ( " # n o d e - t o - d r u p a l - f o r m " ) . s u b m i t ( f u n c t i o n ( ) { D r u p a l . N o d e j s . s o c k e t . e m i t ( ' m e s s a g e ' , m e s s a g e ) ; r e t u r n f a l s e ; } ) ;
  23. WE'VE GOT A CALLBACK FOR THAT! AND CAN EVEN RESPOND

    n o d e _ t o _ d r u p a l . s e r v e r . e x t e n s i o n . j s e x p o r t s . s e t u p = f u n c t i o n ( c o n f i g ) { p r o c e s s . o n ( ' c l i e n t - m e s s a g e ' , f u n c t i o n ( s e s s i o n I d , m e s s a g e ) { c o n s o l e . l o g ( ' G o t a m e s s a g e f r o m t h e c l i e n t . T a k e a l o o k : ' ) ; c o n s o l e . l o g ( m e s s a g e ) ; / / D o s o m e s t u f f . . . c o n f i g . p u b l i s h M e s s a g e T o C l i e n t ( s e s s i o n I d , { d a t a : { s u b j e c t : ' S u c c e s s ' , b o d y : " H u z z a h ! " } } ) ; } } ;
  24. h t t p : / / g i t

    h u b . c o m / r h 0 / n o d e _ t o _ d r u p a l
  25. h o o k _ n o d e j

    s _ m e s s a g e _ c a l l b a c k ( ) WHICH DEFINES A HANDLER n o d e _ t o _ d r u p a l . m o d u l e f u n c t i o n n o d e _ t o _ d r u p a l _ n o d e j s _ m e s s a g e _ c a l l b a c k ( $ t y p e ) { s w i t c h ( $ t y p e ) { c a s e ' n o d e T o D r u p a l ' : r e t u r n a r r a y ( ' n o d e _ t o _ d r u p a l _ h a n d l e r ' ) ; } r e t u r n f a l s e ; } f u n c t i o n n o d e _ t o _ d r u p a l _ h a n d l e r ( $ m e s s a g e , & $ r e s p o n c e ) { $ m e s s a g e _ b o d y = $ m e s s a g e [ ' m e s s a g e B o d y ' ] ; w a t c h d o g ( ' n o d e _ t o _ d r u p a l ' , $ m e s s a g e _ b o d y , a r r a y ( ) , W A T C H D O G _ I N F O ) ; $ r e s p o n c e = ' M e s s a g e l o g g e d t o W a t c h d o g ! ' ; }
  26. YEP, IT'S A CALLBACK. c o n f i g

    . s e n d M e s s a g e T o B a c k e n d ( )
  27. SPECIFY THE MESSAGE TYPE SEND THE MESSAGE TO DRUPAL. m

    e s s a g e . m e s s a g e T y p e = ' n o d e T o D r u p a l ' ; c o n f i g . s e n d M e s s a g e T o B a c k e n d ( m e s s a g e , f u n c t i o n ( e r r o r , r e s p o n c e , b o d y ) { i f ( e r r o r ) { c o n s o l e . l o g ( ' E r r o r s e n d i n g m e s s a g e t o b a c k e n d . ' , e r r o r ) ; r e t u r n ; } c o n s o l e . l o g ( ' R e s p o n s e f r o m d r u p a l : ' , b o d y ) ; } ) ;
  28. SO WHAT DOES THIS MEAN? Server extensions allow us to

    augment the default node server. There are several useful callbacks at our disposal. The config object is your friend The client can talk to the node server using D r u p a l . N o d e J S . s o c k e t . e m i t ( ) The Node server can talk to Drupal using c o n f i g . s e n d M e s s a g e T o B a c k e n d with a message targeted to a custom drupal handler.
  29. h t t p s : / / g i

    t h u b . c o m / r h 0 / d c h e s s
  30. SETUP CHANNEL IN DRUPAL n o d e j s

    _ s e n d _ c o n t e n t _ c h a n n e l _ t o k e n ( ' d c h e s s _ g a m e _ ' . $ n o d e - > n i d ) ;
  31. TOKEN CHANNEL MESSAGE FROM DRUPAL. n o d e j

    s _ s e n d _ c o n t e n t _ c h a n n e l _ m e s s a g e ( $ m e s s a g e ) ;
  32. TOKEN CHANNEL MESSAGE FROM NODE d c h e s

    s . s e r v e r . j s f u n c t i o n s e n d M e s s a g e T o T o k e n C h a n n e l ( m e s s a g e , c o n f i g ) { i f ( ! m e s s a g e . h a s O w n P r o p e r t y ( ' c h a n n e l ' ) ) { c o n s o l e . l o g ( ' . . . i n v a l i d m e s s a g e o b j e c t w a s p r o v i d e d . ' ) ; r e t u r n ; } i f ( ! c o n f i g . t o k e n C h a n n e l s . h a s O w n P r o p e r t y ( m e s s a g e . c h a n n e l ) ) { c o n s o l e . l o g ( ' . . . c h a n n e l " ' + m e s s a g e . c h a n n e l + ' " d o e s n \ ' t e x i s t . ' ) ; r e t u r n ; } f o r ( v a r s o c k e t I d i n c o n f i g . t o k e n C h a n n e l s [ m e s s a g e . c h a n n e l ] . s o c k e t s ) { c o n f i g . p u b l i s h M e s s a g e T o C l i e n t ( s o c k e t I d , m e s s a g e ) ; } }
  33. h t t p : / / c h e

    s s . t h e o l e s c h o o l . c o m
  34. A FEW THINGS TO NOTE h t t p s

    : / / g i t h u b . c o m / j h l y w a / c h e s s . j s h t t p : / / a n g u l a r j s . o r g /
  35. SOME LAST THOUGHTS Works great with pushing messagesto the client.

    You can build more complex node applicaitons with this... but should you?
  36. THANKS t h e o l e s c h

    o o l . c o m d . o / u s e r / 1 1 4 0 5 8 t w i t t e r . c o m / r h o _ g i t h u b . c o m / r h 0