File tree 5 files changed +144
-0
lines changed 5 files changed +144
-0
lines changed Original file line number Diff line number Diff line change
1
+ const wsConnected = ( ) => ( {
2
+ type : 'WS_CONNECTED'
3
+ } ) ;
4
+
5
+ const wsDisconnected = ( ) => ( {
6
+ type : 'WS_DISCONNECTED'
7
+ } ) ;
8
+
9
+ const chatMessage = ( text , global = true ) => ( {
10
+ type : 'CHAT_MESSAGE' ,
11
+ payload : text ,
12
+ meta : {
13
+ websocket : global
14
+ }
15
+ } ) ;
16
+
17
+ const rootReducer = ( state = [ ] , action ) => {
18
+ switch ( action . type ) {
19
+ case 'CHAT_MESSAGE' :
20
+ return state . concat ( { text : action . payload , meta : action . meta } )
21
+ }
22
+ return state ;
23
+ } ;
24
+
25
+ const store = Redux . createStore (
26
+ rootReducer ,
27
+ Redux . applyMiddleware ( logMiddleware , wsMiddleware )
28
+ ) ;
29
+
30
+ $ ( loadUI ) ;
Original file line number Diff line number Diff line change
1
+ <!DOCTYPE html>
2
+ < html lang ="en ">
3
+ < head >
4
+ < meta charset ="UTF-8 ">
5
+ < title > Chapter 5. Websockets with Redux</ title >
6
+ </ head >
7
+ < body >
8
+ < div id ="app "> </ div >
9
+
10
+ < script src ="https://code.jquery.com/jquery-3.1.1.slim.min.js "> </ script >
11
+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/redux/3.3.1/redux.min.js "> </ script >
12
+ < script src ="middleware.js "> </ script >
13
+ < script src ="ui.js "> </ script >
14
+ < script src ="app.js "> </ script >
15
+ </ body >
16
+ </ html >
Original file line number Diff line number Diff line change
1
+ const WS_ROOT = "ws://echo.websocket.org/" ;
2
+
3
+ const SOCKET_STATES = {
4
+ CONNECTING : 0 ,
5
+ OPEN : 1 ,
6
+ CLOSING : 2 ,
7
+ CLOSED : 3
8
+ } ;
9
+
10
+ const wsMiddleware = ( { dispatch } ) => next => {
11
+
12
+ const websocket = new WebSocket ( WS_ROOT ) ;
13
+
14
+ Object . assign ( websocket , {
15
+ onopen ( ) {
16
+ active = true ;
17
+ dispatch ( wsConnected ( ) )
18
+ } ,
19
+
20
+ onclose ( ) {
21
+ active = false ;
22
+ dispatch ( wsDisconnected ( ) )
23
+ } ,
24
+
25
+ onerror ( error ) {
26
+ console . log ( `WS Error: ${ error . data } ` ) ;
27
+ } ,
28
+
29
+ onmessage ( event ) {
30
+ const message = JSON . parse ( event . data )
31
+
32
+ Object . assign ( message , { meta : { fromWebsocket : true } } ) ;
33
+
34
+ dispatch ( message ) ;
35
+ }
36
+ } ) ;
37
+
38
+ return action => {
39
+ if ( websocket . readyState === SOCKET_STATES . OPEN &&
40
+ action . meta &&
41
+ action . meta . websocket ) {
42
+
43
+ // Remove action metadata before sending
44
+ const cleanAction = Object . assign ( { } , action , {
45
+ meta : undefined
46
+ } ) ;
47
+ websocket . send ( JSON . stringify ( cleanAction ) ) ;
48
+ }
49
+
50
+ next ( action ) ;
51
+ } ;
52
+ } ;
53
+
54
+ const logMiddleware = ( { getState, dispatch } ) => ( next ) => ( action ) => {
55
+ console . log ( `Action: ${ action . type } ` , action ) ;
56
+
57
+ next ( action ) ;
58
+ } ;
Original file line number Diff line number Diff line change
1
+ const renderMessage = message => `<li>${ message . text } <i>${ JSON . stringify ( message . meta ) } </i></li>` ;
2
+
3
+ const updateUI = ( ) => {
4
+ const messages = store . getState ( ) ;
5
+
6
+ $ ( '.messages > ul' ) . html ( messages . map ( renderMessage ) ) ;
7
+ } ;
8
+
9
+ const handleAdd = ( ) => {
10
+ const $message = $ ( '.messages > input[type=text]' ) ;
11
+ const $global = $ ( '.messages > input[type=checkbox]' ) ;
12
+
13
+ store . dispatch (
14
+ chatMessage (
15
+ $message . val ( ) ,
16
+ $global . is ( ':checked' )
17
+ ) ) ;
18
+
19
+ $message . val ( '' ) ;
20
+ } ;
21
+
22
+ const loadUI = ( ) => {
23
+ $ ( '#app' ) . append ( `
24
+ <div class="messages">
25
+ <h2>Websocket messages:</h2>
26
+ <ul></ul>
27
+ <input type="checkbox" checked />
28
+ <label for="">Send to server</label>
29
+ <br/>
30
+ <input type="text" />
31
+ <button>Send</button>
32
+ </div>
33
+ ` ) ;
34
+
35
+ store . subscribe ( updateUI ) ;
36
+
37
+ $ ( document ) . on ( 'click' , '.messages > button' , handleAdd ) ;
38
+
39
+ updateUI ( ) ;
40
+ } ;
You can’t perform that action at this time.
0 commit comments