Örnek

Primerface ve Atmosphere ile Basit Bir Web Socket Örneği

Bu yazıda Primefaces 6.2 de Web Socket ile sunucudan istemciye socket açıp veri push nasıl edildiği basit bir örnekle gösterilecektir. Tomcat 8 kullanılacaktır. Pimefaces Web Socket kütüphanesi olan Atmosphere'i ile çalışmaktadır. Öncelikle primefaces ve CDI desteği eklemek gerekiyor. Bunun için aşağıdaki bağımlılıklar eklenmeli:
<dependencies>
	<dependency>
		<groupId>com.sun.faces</groupId>
		<artifactId>jsf-api</artifactId>
		<version>2.2.17</version>
	</dependency>
	<dependency>
		<groupId>com.sun.faces</groupId>
		<artifactId>jsf-impl</artifactId>
		<version>2.2.17</version>
	</dependency>
	<dependency>
		<groupId>org.primefaces</groupId>
		<artifactId>primefaces</artifactId>
		<version>6.2</version>
	</dependency>

	<dependency>
		<groupId>org.jboss.weld.servlet</groupId>
		<artifactId>weld-servlet-shaded</artifactId>
		<version>3.0.4.Final</version>
	</dependency>

	<dependency>
		<groupId>org.atmosphere</groupId>
		<artifactId>atmosphere-runtime</artifactId>
		<version>2.4.6</version>
	</dependency>

	<dependency>
		<groupId>org.atmosphere</groupId>
		<artifactId>atmosphere-runtime-native</artifactId>
		<version>2.4.6</version>
	</dependency>

	<dependency>
		<groupId>org.atmosphere</groupId>
		<artifactId>atmosphere-cdi</artifactId>
		<version>2.4.21</version>
	</dependency>

</dependencies>
bu şekilde JSF 2, Primefaces 6.2, CDI için Weld servlet ve atmosphere projesi için gerekli kütüphaneler eklenmiş olacaktır. CDI kurulumu için bakınız : www.fibiler.com/Tomcat-ile-CDI-Kullanimi_Ipucu_26969 Web.xml aşağıdaki gibi gerekli şeyler eklenmelidir :
<context-param>
	<param-name>primefaces.PUSH_SERVER_URL</param-name>
	<param-value>http://localhost:8080/pfpush</param-value>
</context-param>

<servlet>
	<servlet-name>Faces Servlet</servlet-name>
	<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>Faces Servlet</servlet-name>
	<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<servlet>
	<servlet-name>Push Servlet</servlet-name>
	<servlet-class>org.primefaces.push.PushServlet</servlet-class>
	<init-param>
		<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
		<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
	<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
	<servlet-name>Push Servlet</servlet-name>
	<url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
Öncelikle Push Servlet servlet tanımlanmıştır. Eğer local'de bir context içinde çalışıyorsa web projesi primefaces.PUSH_SERVER_URL değerinin girilmesi gereklidir. pfpush web projenizin adıdır. Bir değeri artıran bir sayfa yapalım. Bu sayfada bir düğme tıklandığında değer bir artsın ve değişiklikler tüm ilgili istemcilere gönderilsin. Sayfa aşağıdaki gibi olabilir:
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>

<h:form>
	<h:outputText value="#{counterView.count}" styleClass="display" />
	<p:commandButton value="Click" actionListener="#{counterView.increment}" />
</h:form>

<p:socket onMessage="handleMessage" channel="/counter" />

<script type="text/javascript">
	function handleMessage(data) {
		$('.display').text(data);
	}
</script>
	
</h:body>
</html>
Düğme tıklandığında counterView bean'indeki değer bir artırılmaktadır. p:socket ile bir web socket yaratılmıştır ve channel ile kanal adı /counter olarak verilmiştir. Kanala yeni veri geldiğinde handleMessage yöntemi çağrılacaktır. Bu yöntem de .display style class'lı nesnenin içeriğini değiştirecektir. CounterView bean'i aşağıdaki gibidir :
import javax.annotation.PiostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.push.EventBus;
import org.primefaces.push.EventBusFactory;

@ManagedBean
@ApplicationScoped
public class CounterView {

	private volatile int count;
	
	private EventBus eventBus;
	
	@PostConstruct
	public void init() {
		eventBus = EventBusFactory.getDefault().eventBus();
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	
	}

	public void increment() {
		count++;
		
		if(eventBus!=null) {
			eventBus.publish("/counter", String.valueOf(count));	
		}
		
	}
}
Düğmeye tıklandığında increment() yöntemi çağrılacaktır. Bu yöntemde counter değerini bir artıracak ve yeni veri girildiğini publish edecektir. Bu şekilde /counter kanalına bağlanmış tüm socket'ler veriyi alacaktır. CounterResource adında bir kaynak aşağıdaki gibi yaratılmalıdır:
import org.primefaces.push.annotation.OnMessage;
import org.primefaces.push.annotation.PushEndpoint;
import org.primefaces.push.impl.JSONEncoder;

@PushEndpoint("/counter")
public class CounterResource {

	@OnMessage(encoders = { JSONEncoder.class })
	public String onMessage(String count) {
		return count;
	}

}
Bu kaynak bir mesaj geldiğinde hangi verinin socket'e yazılacağını belirtir. İkinci bir sayfa yaparak socket'in farklı sayfalarda da çalışacağını test edelim:
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>

<h:form>
	<h:outputText value="" styleClass="display" />
</h:form>

<p:socket onMessage="handleMessage" channel="/counter" />

<script type="text/javascript">
	function handleMessage(data) {
		$('.display').text(data);
	}
</script>
	
</h:body>
</html>
Bu sayfada da bir socket yaratıyoruz. Socket'e mesaj geldiğinde handleMessage çağrılıyor ve değeri gösteren bölüme yeni değer yazılıyor. counter.jsf sayfasını çalıştırınca ve düğmeye basınca değerin hem bu sayfada hem de diğer sayfada değiştiğini görebilirsiniz. Developer aracında WS sekmesi ile socket bağlantıları görülebilir.
zafer.teker , 07.03.2020

Bu Sayfayı Paylaş:

Fibiler Üyelerinin Yorumları


Tüm üyeler içeriklere yorum ekleyerek katkıda bulunabilir : Yorum Gir



Bu Sayfayı Paylaş:

İletişim Bilgileri

Takip Et

Her Hakkı Saklıdır. Bu sitede yayınlanan tüm bilgi ve fikirlerin kullanımından fibiler.com sorumlu değildir. Bu sitede üretilmiş , derlenmiş içerikleri, fibiler.com'u kaynak göstermek koşuluyla kendi sitenizde kullanılabilirsiniz. Ancak telif hakkı olan içeriklerin hakları sahiplerine aittir