Skip to content

Commit a89b049

Browse files
committed
updates
1 parent 864c83f commit a89b049

22 files changed

+2239
-2238
lines changed

README.md

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
1-
# long-polling-redis
2-
Example App showing client side long polling using Spring MVC and Redis Pub/Sub.
3-
4-
Uses Spring 3 MVC, Spring Data Redis, JQuery on the front-end, and an embedded Redis Server.
5-
6-
### Overview
7-
8-
A naive approach to front-end querying of the backend for new emails, messages, alerts, etc. is to poll every *x* seconds.
9-
In Javascript, this is usually done using the `setInterval()` function.
10-
11-
For example, if one were to design a email app similar to GMail, the user will expect new incoming
12-
messages to be shown in the inbox count automatically (i.e. without having to constantly refresh the page).
13-
14-
Polling again and again is a waste of resources on both the client and server, especially when the frequency
15-
of polling is far greater than new incoming messages are received.
16-
17-
A better way to approach the problem is by using async requests on a pubsub channel on the backend, along
18-
with a recursive function on the front-end that only makes new requests when the old has actually returned.
19-
20-
21-
### Instructions
22-
23-
From the command line, run:
24-
25-
````
26-
$ mvn tomcat7:run
27-
````
28-
29-
Open your browser to [http://127.0.0.1:8080](http://127.0.0.1:8080).
30-
31-
In the input box, add messages.
32-
33-
The left column shows the output from a front-end approach using async requests on the server and a recursive
34-
function on the front-end to re-call itself upon completion / timeout of each request. Requests on the back-end
35-
will simply block (though without holding the request thread) until Redis informs the waiting requests that a new message
36-
has been added.
37-
38-
The right column shows the traditional attempt with polling. Every 10 seconds (configurable in `app.properties` file),
39-
the front-end will make a call to the server requesting new messages. The server responds immediately with the result.
40-
If messages are created less frequently than the poll time, most of the requests are wasted.
1+
# long-polling-redis
2+
Example App showing client side long polling using Spring MVC and Redis Pub/Sub.
3+
4+
Uses Spring 3 MVC, Spring Data Redis, JQuery on the front-end, and an embedded Redis Server.
5+
6+
### Overview
7+
8+
A naive approach to front-end querying of the backend for new emails, messages, alerts, etc. is to poll every *x* seconds.
9+
In Javascript, this is usually done using the `setInterval()` function.
10+
11+
For example, if one were to design a email app similar to GMail, the user will expect new incoming
12+
messages to be shown in the inbox count automatically (i.e. without having to constantly refresh the page).
13+
14+
Polling again and again is a waste of resources on both the client and server, especially when the frequency
15+
of polling is far greater than new incoming messages are received.
16+
17+
A better way to approach the problem is by using async requests on a pubsub channel on the backend, along
18+
with a recursive function on the front-end that only makes new requests when the old has actually returned.
19+
20+
21+
### Instructions
22+
23+
From the command line, run:
24+
25+
````
26+
$ mvn tomcat7:run
27+
````
28+
29+
Open your browser to [http://127.0.0.1:8080](http://127.0.0.1:8080).
30+
31+
In the input box, add messages.
32+
33+
The left column shows the output from a front-end approach using async requests on the server and a recursive
34+
function on the front-end to re-call itself upon completion / timeout of each request. Requests on the back-end
35+
will simply block (though without holding the request thread) until Redis informs the waiting requests that a new message
36+
has been added.
37+
38+
The right column shows the traditional attempt with polling. Every 10 seconds (configurable in `app.properties` file),
39+
the front-end will make a call to the server requesting new messages. The server responds immediately with the result.
40+
If messages are created less frequently than the poll time, most of the requests are wasted.

src/main/java/com/studerw/appMsg/AppMsg.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import org.apache.commons.lang3.builder.ToStringBuilder;
44

55
import java.io.Serializable;
6-
import java.util.Comparator;
76

87
/**
98
* @author William Studer

src/main/java/com/studerw/appMsg/MemoryAppMsgRepo.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import org.slf4j.LoggerFactory;
66
import org.springframework.beans.factory.annotation.Autowired;
77
import org.springframework.beans.factory.annotation.Value;
8-
import org.springframework.data.redis.core.RedisTemplate;
98
import org.springframework.data.redis.core.StringRedisTemplate;
109
import org.springframework.stereotype.Component;
1110

src/main/java/com/studerw/config/ApplicationConfig.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.studerw.config;
22

3-
import com.studerw.appMsg.AppMsg;
43
import com.studerw.appMsg.AppMsgHandler;
54
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
@@ -13,18 +12,14 @@
1312
import org.springframework.core.env.Environment;
1413
import org.springframework.data.redis.connection.RedisConnectionFactory;
1514
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
16-
import org.springframework.data.redis.core.RedisTemplate;
1715
import org.springframework.data.redis.core.StringRedisTemplate;
1816
import org.springframework.data.redis.listener.PatternTopic;
1917
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
2018
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
2119
import org.springframework.stereotype.Controller;
22-
import org.springframework.web.context.request.async.DeferredResult;
2320
import redis.embedded.RedisServer;
2421

2522
import java.io.IOException;
26-
import java.util.List;
27-
import java.util.concurrent.ConcurrentHashMap;
2823

2924
import static org.springframework.context.annotation.ComponentScan.Filter;
3025

src/main/java/com/studerw/config/WebAppInitializer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.studerw.config;
22

33
import org.springframework.web.filter.CharacterEncodingFilter;
4-
import org.springframework.web.filter.DelegatingFilterProxy;
54
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
65

7-
import javax.servlet.*;
6+
import javax.servlet.Filter;
7+
import javax.servlet.ServletRegistration;
88

99
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
1010

src/main/java/com/studerw/error/CustomErrorController.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
package com.studerw.error;
22

3-
import java.text.MessageFormat;
4-
5-
import javax.servlet.http.HttpServletRequest;
6-
import javax.servlet.http.HttpServletResponse;
7-
3+
import com.google.common.base.Throwables;
84
import org.springframework.http.HttpStatus;
95
import org.springframework.stereotype.Controller;
106
import org.springframework.ui.Model;
117
import org.springframework.web.bind.annotation.RequestMapping;
128

13-
import com.google.common.base.Throwables;
9+
import javax.servlet.http.HttpServletRequest;
10+
import javax.servlet.http.HttpServletResponse;
11+
import java.text.MessageFormat;
1412

1513
@Controller
1614
class CustomErrorController {

src/main/java/com/studerw/error/ExceptionHandler.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package com.studerw.error;
22

3+
import com.google.common.base.Throwables;
34
import org.springframework.web.bind.annotation.ControllerAdvice;
45
import org.springframework.web.context.request.WebRequest;
56
import org.springframework.web.servlet.ModelAndView;
67

7-
import com.google.common.base.Throwables;
8-
98
/**
109
* General error handler for the application.
1110
*/
@@ -22,4 +21,4 @@ public ModelAndView exception(Exception exception, WebRequest request) {
2221
modelAndView.addObject("errorMessage", Throwables.getRootCause(exception));
2322
return modelAndView;
2423
}
25-
}
24+
}

src/main/java/com/studerw/support/web/FlashMessageHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.studerw.support.web;
22

3-
import static com.studerw.support.web.FlashMessage.MESSAGE_ATTRIBUTE;
4-
53
import org.springframework.ui.Model;
64
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
75

6+
import static com.studerw.support.web.FlashMessage.MESSAGE_ATTRIBUTE;
7+
88
public final class FlashMessageHelper {
99

1010
private FlashMessageHelper() {

src/main/resources/logback.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717

1818
<logger name="com.github.kstyrc" level="DEBUG" />
1919
<logger name="org.springframework" level="WARN" />
20-
<logger name="com.studerw" level="INFO" />
20+
<logger name="com.studerw" level="DEBUG" />
2121
</configuration>
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
view.index.title=Home page
2-
signup.success=Congratulations {0}! You have successfully signed up.
3-
4-
# Validation messages
5-
notBlank.message = The value may not be empty!
1+
view.index.title=Home page
2+
signup.success=Congratulations {0}! You have successfully signed up.
3+
4+
# Validation messages
5+
notBlank.message = The value may not be empty!
66
email.message = The value must be a valid email!

0 commit comments

Comments
 (0)