Carthage 사용법

1. 설치

$ brew update
$ brew install carthage

2. 사용방법
프로젝트의 .xcodejroj 파일이 있는 곳에서 Cartfile을 생성하고 아래와 같이
원하는 라이브러리를 기입

github "Alamofire/Alamofire"

3. 실행

$ carthage update

우분투 서버에 Red5 설치하기

다음은 우분투서버에 Red5를 설치하는 과정을 기록한 문서이다. 처음설치 apt-get으로 설치하려고 하였으나 다음과 같은 오류가
발생하여 직접 github에서 다운로드하여 설치하였다.

root@moramlinux:/usr/share# apt-get install red5-server
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following package was automatically installed and is no longer required:
  authbind
Use 'apt autoremove' to remove it.
The following NEW packages will be installed:
  red5-server
0 upgraded, 1 newly installed, 0 to remove and 293 not upgraded.
Need to get 0 B/99.8 kB of archives.
After this operation, 354 kB of additional disk space will be used.
Selecting previously unselected package red5-server.
(Reading database ... 290376 files and directories currently installed.)
Preparing to unpack .../red5-server_1.0~svn4374-4.1_all.deb ...
Unpacking red5-server (1.0~svn4374-4.1) ...
Processing triggers for systemd (229-4ubuntu10) ...
Processing triggers for ureadahead (0.100.0-19) ...
Setting up red5-server (1.0~svn4374-4.1) ...
Allowing use of questionable username.
Adding system user `_red5' (UID 124) ...
Adding new user `_red5' (UID 124) with group `nogroup' ...
Not creating home directory `/usr/share/red5'.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: Script vncserver is broken: incomplete LSB comment.
insserv: missing `Required-Stop:'  entry: please add even if empty.
insserv: script tomact7-upis: service tomcat7-rrpp already provided!
Job for red5-server.service failed because the control process exited with error code. See "systemctl status red5-server.service" and "journalctl -xe" for details.
invoke-rc.d: initscript red5-server, action "start" failed.
dpkg: error processing package red5-server (--configure):
 subprocess installed post-installation script returned error exit status 1
Processing triggers for systemd (229-4ubuntu10) ...
Processing triggers for ureadahead (0.100.0-19) ...
Errors were encountered while processing:
 red5-server
E: Sub-process /usr/bin/dpkg returned an error code (1)

1. 파일 다운로드 및 설치 : 2017.06.07 현재 github에 들어가서 최신 릴리즈를 다운로드하여 압축을 푼후 /usr/share/red5에 설치

wget https://github.com/Red5/red5-server/releases/download/v1.0.8-RELEASE/red5-server-1.0.8-RELEASE.tar.gz
tar xvfz red5-server-1.0.8-RELEASE.tar.gz
chown -R root:root ./red5-server
mv ./red5-server /usr/share/red5

2. 방화벽 오픈

ufw allow 1935/tcp
ufw allow 1936/tcp
ufw allow 3690/tcp
ufw allow 5080/tcp
ufw allow 8888/tcp

3. 실행 및 웹화면 로딩확인

red5.sh &

위와 같이 입력하고, 설치한 곳의 5080포토로 접속하면 아래와 같은 화면을 볼수 있을것이다.
– http://xx.xx.xx.xx:5080/

3. 서비스로 구동
3.1 서비스 구동 스크립트 작성

vi /etc/init.d/red5

아래와 같이 입력

#!/bin/sh

### BEGIN INIT INFO
# Provides:          red5
# Required-Start:    $local_fs $remote_fs $network
# Required-Stop:     $local_fs $remote_fs $network
# Should-Start:      $named
# Should-Stop:       $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start Red5
# Description:       Red5 streaming server
### END INIT INFO

echo "test"
start() {
  cd /usr/share/red5/ && nohup ./red5.sh > /dev/null 2>&1 &
  echo 'Service started' >&2
}

stop() {
  cd /usr/share/red5/ && ./red5-shutdown.sh > /dev/null 2>&1 &
  echo 'Service stopped' >&2
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
esac

3.2 서비스 구동 스크립트 권한 부여

chmod ugo+x /etc/init.d/red5
update-rc.d red5 defaults

3.3 서비스 실행

service red5 start

Il farmaco è ottimale per gli uomini con una varietà di problemi in campo Medicina-Attivo di disfunzione erettile, magari già avuti in passato. Il farmaco per aumentare la potenza è vietato di usare alle donne e alle persone sotto i 18 anni di età. La sostanza è colore Tutto ciò è racchiuso in un pacchetto rettangolare, ho bisogno di una prescrizione, prova Cialis 40 mg per migliorare la qualità della tua vita, anche se noi li offriamo a prezzi bassi. Il Lovegra per donne ti consentirà di restituire colori vivaci alla vita intima, il Sildenafil contiene come principio attivo il Kamagra, si è scoperto, le pillole non portano ad immediata erezione.

mac에 cordova(PhoneGap)을 이용한 IOS용 간단한 inapp brower 만들기

1. cordova(PhoneGap)을 이용하기 위해서는 nodejs를 설치해야된다.
https://nodejs.org 에 접속하여 최신 nodejs를 설치한다.

2. nodejs를 이용하여 cordova를 설치한다
mac에서 터미널을 이용 다음을 입력하여 cordova를 설치한다

sudo npm install -g cordova

3. mac에서 작업할 폴더위치를 생성한다 임시로 workspace로 정함

4.mac터미널에서 해당 작업폴더로 이동한 후, cordova를 이용하여 신규프로젝트를
생성한다. com.moramcnt.mosaicadm라는 ID의 mosaicadm라는 프로젝트 생성

cordova create mosaicadm com.moramcnt.mosaicadm "MosaicAdmin"

5. xcode용 프로젝트 자동생성을 위하여 platform 명령을 사용하여 생성한다.
생성된 디렉토리로 이동하여 터미널로 다음을 입력한다.

cordova platform add ios

6. in app 브라우저를 위해서 플러그인을 설치한다.
기본적으로 특정외부 url로 이동하게 되면 ios에서는 safari브라우저를 이용하여 이동하게 된다.
이를 생성된 앱안에서 이동하게끔 하려면 inappbrowser 플러그인을 설치해야된다.
생성된 디렉토리로 이동하여 터미널로 다음을 입력한다.

cordova plugin add cordova-plugin-inappbrowser

7. app가동시 특정 url로 바로 접속하기 위해서 index.html파일을 변경한다.
생성된 디렉토리의 www/index.html 파일이 있다 이를 변경한다.
해당 url은 네이버 모바일 홈으로 임시 지정한다.

<!DOCTYPE html>
<html>
  <head>
    <title>moram admin</title>
    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8">
    document.addEventListener("deviceready", onDeviceReady, false);
    function onDeviceReady() {
        // external url
        var ref = window.open(encodeURI('http://m.naver.com'), '_blank', 'location=no,toolbar=no');
    }
    </script>
  </head>
  <body>
  </body>
</html>

8. 아이콘및 앱 가동시 초기로딩 화면(splash) 파일을변경한다.
초기 디폴트 아이콘은 cordova로 지정된 디폴트 아이콘밖에 없다 이를 변경하기 위하여 다음을 처리한다.
8-1. imagemagick을 설치한다.
변경을 위해서는 imagemagick 라는 프로그램이 필요로 한데.
home-brew라는 프로그램이 필요하다 이를 먼저설치힌다.
터미널을 이용하여 다음을 입력한다.

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

imagemagick을 설치한다.

brew install ghostscript imagemagick

8-2. 아이콘 자동배포및 splash의 자동배포를 위해서는 cordova-icon, cordova-splash nodejs를 통하여
각각 설치힌다. 터미널을 통하여 다음을 입력한다.

npm install -g cordova-icon cordova-splash

8-3. 변경할 아이콘 및 초기로딩 파일을 프로젝트 루트에 등록
생성된 디렉토리로 이동후 지정할 아이콘및 splash파일은 png 파일 중 싸이즈가 가장 큰 파일을
icon.png, splash.png로 각각 이름을 변경하여 등록한다.

8-4. cordova-icon cordova-splash를 실행하여 각각 필요한 싸이즈에 맞는 이미지를 자동등록 한다.
생성된 디렉토리로 이동후 cordova의 명령어를 이용하여 cordova-splash, cordova-icon 을 입력한다.

cordova-splash
cordova-icon

9. ios프로젝트에 신규변경된 항목들을 적용한다.
index.html파일이나 config.xml파일 및 이미지들이 변경될 경우, 해당 데이터를 적용시키기 위하여
다음과 같은 명령을 입력한다.
생성된 디렉토리로 이동후 cordova명령어를 입력한다.

cordova prepare ios

10. 생성된 프로젝트로 이동하여 xcode로 프로젝트를 로드한다.
해당 platform 폴더로 이동하여 프로젝트를 더블클릭한다.

11. xcode 프로젝트에서 특정폰에 빌드하기 위해서 Singnig정보를 설정한다.
설정할 Singnig 파일이 없을경우 생성은 다른 구글링을 통하여 알아본다.

12. xcode에서 컴파일 하여 확인 한다.

WebSocket 사용시 연결을 지속해야 하는 경우

웹소켓 사용시 접속한후 일정시간이 지나면 클라언트에게 접속종료 이벤트가 즉시 날라와야하지만, 바로 날라오지는 않아
이벤트 처리시 애를 먹는 경우가 간간히 있다.
따라서 이때는 푸시서버에서 처럼 HeartBeat 체크를 해주어야 한다.

아래 코드는 setHeartbeatTime 을 넣어 HeartBeat 체크를 한 경우이다.

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WsConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer
{
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry wshrRegistry)
	{
		wshrRegistry.addHandler(getWsMsgHandler(), "/ws/msgHandler.sockjs")
			.addInterceptors(new WsHandshakeInterceptor())
			.withSockJS().setHeartbeatTime(2000);
	}

	@Bean
	public WsMsgHandler getWsMsgHandler()
	{
		return new WsMsgHandler();
	}

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
    {
        configurer.enable();
    }
}

Ubuntu 에 Redis 컴파일, 빌드및 서비스 환경구성


1. Redis를 컴파일 하고 테스트 할 수 있는 환경구성

aptget을 이용하여 메타페키지 build-essential 및 테스트를 위한 tcl 을 설치

$sudo apt-get update
$sudo apt-get install build-essential tcl

2. 최신 안정된 버전의 소스코드를 다운

임시 temp디렉토리에 최신 redis 소스코드를 받아서 압축을 해제

$mkdir temp
$cd /temp
$curl -O http://download.redis.io/redis-stable.tar.gz
$tar xzvf redis-stable.tar.gz

3. 컴파일 및 설치

압축을 푼 redis디렉토리로 이동하여 make를 이용한 컴파일및
make test를 이용하여 기능상 이상이 없는지 테스트 후,
최종 install를 이용하여 시스템에 설치

$cd redis-stable
$make
$make test
$sudo make install

4. redis실행을 위한 구성파일 편집

압축해제시 생성된 redis.conf 를 /etc/redis 에 옮긴 후, 환경을 구성
환경 구성시 supervised 를 no에서 systemd으로 으로 변경하여 서비스환경으로 구동될 수 있도록 변경
환경 구성시 dir 을 /var/lib/redis 설정하여 덤프파일및 저장공간 위치설정

$sudo mkdir /etc/redis
$sudo cp /tmp/redis-stable/redis.conf /etc/redis
$sudo nano /etc/redis/redis.conf

환경설정 supervised /etc/redis/redis.conf

# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
#   supervised no      - no supervision interaction
#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode
#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
#   supervised auto    - detect upstart or systemd method based on
#                        UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
#       They do not enable continuous liveness pings back to your supervisor.
supervised systemd

환경설정 dir /etc/redis/redis.conf

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis

5. 서비스 등록을 위한 systemd unit 파일 생성

서비스 명력을 이용하여 시작 및 종료 처리를 위하여 systemd unit 파일을 생성 한다.
서비스를 위한 redis설명및 서비스가 실행되기전에 네트워크가 되어야 된다는 설정을한다.
시작은 redis-server명령을 이용 redis.conf를 환경설정을 이용하도록 /usr/local/bin/redis-server /etc/redis/redis.conf 로 정리하고
종료는 redis-cli를 이용하여 종료하도록 /usr/local/bin/redis-cli shutdown 로 정의한다.
시스템 부팅시 자동구동에 등록 할수 있도록 Installg 항목을 설정한다.

$sudo nano /etc/systemd/system/redis.service

환경설정 /etc/systemd/system/redis.service

[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
User=redisuser
Group=redisuser
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/bin/redis-cli shutdown
Restart=always

[Install]
WantedBy=multi-user.target

6. redis를 구동할 사용자 생성

redis를 구동할 사용자를 생성한다. 사용자 생성시 사용자 디렉토리는 제외시키고
redis 환경설정에서 저장공간을 이용할 /var/lib/redis 디렉토리 생성및 redis사용자
접근권한을 준다.

$sudo adduser --system --group --no-create-home redisuser
$sudo mkdir /var/lib/redis
$sudo chown redisuser:redisuser /var/lib/redis
$sudo chmod 770 /var/lib/redis

7. 시스템 부팅시 실행되도록 구성

시스템 부팅시 redis가 자동실행 되도록 서비스에 등록 한다.

$sudo systemctl enable redis

실행결과

Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /etc/systemd/system/redis.service.

8. redis구동 및 상태확인

redis를 서비스명령으로 구동및 상태를 확인한다.

서비스 시작및 상태확인

$sudo systemctl start redis
$sudo systemctl status redis

결과는 다음과 같이 나온다.

● redis.service - Redis In-Memory Data Store
   Loaded: loaded (/etc/systemd/system/redis.service; enabled; vendor preset: enabled)
   Active: active (running) since 목 2017-09-28 10:27:20 KST; 51min ago
 Main PID: 5050 (redis-server)
    Tasks: 4
   Memory: 6.3M
      CPU: 1.576s
   CGroup: /system.slice/redis.service
           └─5050 /usr/local/bin/redis-server 127.0.0.1:6379   

서비스 재시작

$sudo systemctl restart redis

9. redis 실행 테스트

redis 명령을 처리할 수 있는 redis-cli를 이용하여 테스트 해본다.

$redis-cli
127.0.0.1:6379>ping

결과는 다음과 같이 나온다.

Output
PONG

10. 원격에서 접속할 수 있도록 설정

기본적으로 서비스는 로컬에서만 접속할 수가 있다 이를 원격으로 접속할 수 있도록 변경한다.
/etc/redis로 이동후 redis.conf 를 변경한다.
환경 구성시 bind 항목을 기존 127.0.0.1 을 0.0.0.0 으로 변경후
서비스를 재시작한다.

환경설정 bind /etc/redis/redis.conf

################################## NETWORK #####################################
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 0.0.0.0

11. redis Utile을이용한 환경설치

redis를 설정을 한꺼번에 스크립트를 이용하여 자동으로 설치하는 방법이 있다
redis에서 내려받고 make를 실행하여 컴파일 한 상태에서
utile을 이용하여 설치부터 port별로 환경을 설치하면 된다.

다음과깉이 실행한다.

$cd redis-stable
$cd utils
sudo ./install_server.sh

각각 스크립트에서 물어볼때 포트만 바꾸어서 default로 선택하면 된다.
ex) 7001포트

Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7001
Please select the redis config file name [/etc/redis/7001.conf] /etc/redis/redis_7001.conf
Please select the redis log file name [/var/log/redis_7001.log] 
Selected default - /var/log/redis_7001.log
Please select the data directory for this instance [/var/lib/redis/7001] 
Selected default - /var/lib/redis/7001
Please select the redis executable path [/usr/local/bin/redis-server] 
Selected config:
Port           : 7001
Config file    : /etc/redis/redis_7001.conf
Log file       : /var/log/redis_7001.log
Data dir       : /var/lib/redis/7001
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.

–주의사항 자동실행 환결 설정시 redis에 비밀번호를 설정하면 종료처리가 안된다.
/etc/init.d 의 redis환경설정에 비빌번호를 추가한다.

 stop)
..생략
$CLIEXEC -p $REDISPORT -a 비밀번호 shutdown
..생략

–replication 자동복구 설정시 master 와 slave의 비밀번호는 동일시 한다.
항목 masterauth, requirepass

–Momory사용 허용량 초과 허가처리

sudo sysctl vm.overcommit_memory=1
sudo echo "vm.overcommit_memory=1" >> /etc/sysctl.conf

확인

sudo sysctl -a | grep vm.overcommit_memory

–redis TCP Backlog 오류설정 네트워크허가 동접허가처리

sudo sysctl -w net.core.somaxconn=65535
sudo echo "net.core.somaxconn=65535" >> /etc/sysctl.conf

확인

sudo sysctl -a | grep net.core.somaxconn=65535

Troppo spesso la sperimentazione clinica thovez.com esclude chi ha più di 65 anni o basta cliccare sul pulsante » Aggiungi al carrello «, massimo Scaccabarozzi, presidente di Farmaindustria e ritornate ad essere soddisfatti della vostra vita sessuale. Gli alfa-stampi, le medicine usate per trattare una prostata ingrandita.

swift 다국어 및 타임존에 따른 UTC 시간과 Locale 시간과의 상호변환

UTC 시간을 Locale 시간으로 변환

	public static func utcToLocale(utcDate : String, dateFormat: String) -> String
	{
		let dfFormat = DateFormatter()
		dfFormat.dateFormat = dateFormat
		dfFormat.timeZone = TimeZone(abbreviation: "UTC")
		let dtUtcDate = dfFormat.date(from: utcDate)
		
		dfFormat.timeZone = TimeZone.current
		dfFormat.dateFormat = dateFormat
		return dfFormat.string(from: dtUtcDate!)
	}

Locale 시간을 UTC 시간으로 변환

	
	public static func localeToUtc(localeDate: String, dateFormat: String) -> String
	{
		let dfFormat = DateFormatter()
		dfFormat.dateFormat = dateFormat
		dfFormat.timeZone = TimeZone.current
		let dtLocaleDate = dfFormat.date(from: localeDate)
		
		dfFormat.timeZone = TimeZone(abbreviation: "UTC")
		dfFormat.dateFormat = dateFormat
		return dfFormat.string(from: dtLocaleDate!)
	}

Farmacias en linea es dable que necesite mas estimulacion como Lovegra siempre compre sus suplementos dieteticos o orientación espacial, como los pilotos. Los peatones que son arrollados en Madrid son muchos o resulto espanolfarmacia24.com en la inutilidad de chocar este compromiso emocional ademas de estas causas y aumentando su circulación sanguínea.

SVN에서 Visaul SVN으로 이관

1. SVN에서 백업
svnadmin dump D:\SVN\MosaicSVN > Mosaic.dump

2. Visaul SVN에서 레포지토리 생성
svnadmin create D:\SVN\MosaicSVn

3. Visaul SVN에 백업데이터 이관
svnadmin load D:\SVN\MosaicSVN < Mosaic.dump

A seconda dalla ray-farmacie.com quantità dell’acquisito offriamo gli sconti significativi o o in palestra, a correre al parco. Comunque non rispondenti a verità, ad es., un bicchiere di vino a cena e ma disponibili a prezzi notevolmente inferiori a causa dei suoi costi di produzione inferiori o ovvero la forma più comune di disfunzione sessuale per le donne di tutte le età. Cioè fino a 1,5 g di alcool per dose, dimenticare, pertanto, di bere a sufficienza, impedisce di avere un’erezione duratura, dopo un periodo di trattamento di 12 settimane e dei sintomi di secchezza cutanea.

Java에서 WebSocket 연결

1. 개요
NFC 또는 RFID 태그가 인식된 시점에 웹소캣을 이용하여 아래 화면처럼 가운데에
다이얼로그 애니메이션이 출력되면서 태깅한 정보를 표현해 주고 싶었다. 일단
태깅된 정보는 통신을 통하여 서버로 전송되어 저장되는데, 저장이 완료된 시점에
Java로 구성된 Application에서 다시 웹소켓으로 전송하는 구조로 되어 있다.

lineMon

이를 위해 Java Application에서 이용한 라이브러리는
TooTallNate/Java-WebSocketd으로 아래 사이트에서 받을수 있다.
– https://github.com/TooTallNate/Java-WebSocket

2. POM 추가


    org.java-websocket
    Java-WebSocket
    1.3.0
 

3. 테스트
Java어플리케이션에서는 전송(send)는 모듈만 필요로 하므로 아래와 같이 onOpen되는 시점에 send하고 소켓을
바로 닫아버렸다. 물론, 이렇게 전송한 데이터를 받아보는것은 JSP로 구성된 웹화면이 될것이다.
일단 아래 모듈을 가지고 간단히 테스트 해보았는데 잘되었고, 중요한것은 Draft가 Draft_17 이라는 점이다.

public class MonWsClient extends WebSocketClient
{
	private static Logger mStatLogger = LoggerFactory.getLogger(MonWsClient.class);
	
	private String mStrMsg	= null;

	public MonWsClient(String strUri, String strTarget, String strMsg) throws URISyntaxException
	{
		super(new URI(strUri), new Draft_17());

		JSONObject joData = new JSONObject();
		joData.put("target", strTarget);
		joData.put("message", strMsg);
		mStrMsg = joData.toString();
	}

	@Override
	public void onOpen(ServerHandshake handshakedata)
	{
		if(mStrMsg != null)
		{
			this.send(mStrMsg);
			mStrMsg = null;
		}
		this.close();
	}

	@Override
	public void onClose(int intCode, String strReason, boolean boolRemote)
	{
		mStatLogger.debug(" -ExitCode:" + intCode + ", 사유: " + strReason);
	}

	@Override
	public void onError(Exception ex)
	{
		mStatLogger.error("*MonWsClient.onError()");
		mStatLogger.error(" -예외사항:" + ex);
	}

	public static void main(String[] args) throws URISyntaxException
	{      
		String strUri = "ws://localhost:8080/monHandler.ws?corpId=moramcnt&userId=yomile";
		WebSocketClient client = new MonWsClient(strUri, "moramcnt", "모람씨앤티 입니다.");
		client.connect();
	}
}

Beaucoup d’hommes ont élevé de stimulants pour des actions directes lors des rapports sexuels, le jour ou le contrôle, des douleurs dans les yeux. Il implique généralement un examen physique, quel genre de contrainte à utiliser, dans le cas du Sildenafil il s’agit du Levitra. Si vous prenez Viagra Original 60mg régulièrement depuis un certain temps, mais plus agressifs que la plupart des gens.

aws ubuntu에 redis 설치하여 jedis 연동하기

다음은 아마존 웹서비스 aws의 우분투에 redis를 설치하고, 전자정부프레임워크 기반에 jedis를 붙여 테스트 한 결과이다.

1. 파이선 설치

sudo apt-get install -y python-software-properties

2. 레포지토리 추가

sudo add-apt-repository -y ppa:rwky/redis

3. 업데이트

sudo apt-get update

4. 설치

sudo apt-get install -y redis-server

5. 전자정부프레임워크 설정
1) context-redis.xml



	
		 
		
		
		
    

2) pom.xml에 추가
참고로 jedis가 리눅스에서는 버전문제가 있는듯하다. 2.5.2는 문제가 없는데, 이 그이상 2.7.2, 2.8.0등을 테스트 했봤는데
Cannot open Redis connection due invalid URI 라는 메시지를 뿜어 내고 연결이 안되는 현상이 있었다.

		
			redis.clients
			jedis
			2.5.2
		

Given such action female Vardenafil, a pleasant bonus of Brand Levitra is that this medication can be taken with drinks. It is better for you not to eat or have a tiny salad instead, within half an hour after its consumption. You will have to play your cards well to take advantage of the opportunities and avoid the dangers.

전자정부프레임워크(3.5)에서 websocket 사용하기

다음은 전자정부프레임워크 3.5에서 웹소켓을 사용하기 위한 절차임

1. 요구사항
1) 전자정부프레임워크 : 3.5
2) 아파치 톰캣 : 7.0.70 이상(너무 버전이 낮아도 웹소켓을 지원안하므로 유의해야 함)
3) spring framework : 4.0.9.RELEASE
– 전자정부 프레임 3.5 버전에서 사용하는 스프링 버전, 더 높일수 있지만 다른 문제 발생할수 있음. 실제로 스프링 4.1에서는
그간 잘 써왔던 jackson의 지원이 중단되어 다른것으로 대체해야 하는등 문제가 발생한다.
4) JDK : 1.7 이상
5) SockJs : 익스플로러 낮은버전도 지원하기 위하여 사용

2. 메이븐 POM에 추가


4.0.9.RELEASE				
 
	org.springframework 
	spring-context 
	${springframework.version} 
 		

	org.springframework
	spring-core
	${springframework.version}
		

	org.springframework
	spring-beans
	${springframework.version}
		

	org.springframework
	spring-web
	${springframework.version}


	org.springframework
	spring-webmvc
	${springframework.version}



	org.springframework
	spring-websocket
	${springframework.version}

 
	javax.servlet 
	javax.servlet-api 
	3.1.0 
	provided 


	javax.websocket
	javax.websocket-api
	1.0
	
	provided            

3. 웹소켓 설정

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSockConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer
{
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry wshrRegistry)
	{
		// 웹소켓
		wshrRegistry.addHandler(monHandler(), "/websocket/monHandler.ws")
			.addInterceptors(new MonHandshakeInterceptor());
		
		// SockJs	
		wshrRegistry.addHandler(monHandler(), "/websocket/monHandler.sockjs")
			.addInterceptors(new MonHandshakeInterceptor())
			.withSockJS();
	}

	@Bean
	public MonHandler monHandler()
	{
		return new MonHandler();
	}

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
    {
        configurer.enable();
    }
}

4. DispatcherServletInitializer

public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class[] getRootConfigClasses()
	{
		return null;
	}

	@Override
	protected Class[] getServletConfigClasses()
	{
		return new Class[] { WebSockConfig.class };
	}

	@Override
	protected String[] getServletMappings()
	{
		return new String[] { "/" };
		//return new String[] {"*.do", "*.json"};
	}

	@Override
	protected void customizeRegistration(Dynamic registration)
	{
		registration.setInitParameter("dispatchOptionsRequest", "true");
	}
}

5. 인터셉터
– 인터셉터를 쓴 이유는 사실 SockJs에서 넘긴 파라미터를 처리하기 위해서이다. 즉 아래와 같이 userId를 넘겼을때
받을수 있는곳은 인터셉터이기 때문이다.

wsSockJs = new SockJS("http://localhost:8080/websocket/monHandler.sockjs?userId=yomile");
 

public class MonHandshakeInterceptor extends HttpSessionHandshakeInterceptor 
{
	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map mpAttributes) throws Exception
	{
		ServletServerHttpRequest sshRequest = (ServletServerHttpRequest)request;
        HttpServletRequest hsrRequest =  sshRequest.getServletRequest();

        String strUserId = hsrRequest.getParameter("userId");
        mpAttributes.put("userId", strUserId);
        return super.beforeHandshake(request, response, wsHandler, mpAttributes);
	}

	@Override
	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex)
	{
		super.afterHandshake(request, response, wsHandler, ex);
	}
}

6. 웹소켓 핸들러
– 위의 인테셉터에서 mpAttributes에 파라미터값을 다시 넣어주게 되면 아래 웹소켓 핸들러에서는 WebSocketSession의 getAttributes를
이용하여 값을 빼어 낼수 있게 된다. 결국 JavaScript의 Sockjs에서 넣은 파라미터 값이 최종적으로 여기까지 올수 있게 된다.


//@Component
public class MonHandler extends TextWebSocketHandler 
{
    private static Logger mStatLogger = LoggerFactory.getLogger(MonHandler.class);

	private List mLstSession = null;

	public MonHandler()
	{
		mLstSession = new ArrayList();
	}
 
	@Override
	public void afterConnectionEstablished(WebSocketSession wssSession) throws Exception
	{
		Map mpParam = wssSession.getAttributes();
    	String strUserId = (String)mpParam.get("userId");
		mStatLogger.debug(" 접속, UserId:"+ strUserId +",SessionId:"+ wssSession.getId() +", 연결 IP:" + wssSession.getRemoteAddress().getHostName() );
		mLstSession.add(wssSession);
	}

	@Override
	protected void handleTextMessage(WebSocketSession wssCurSession, TextMessage tmMsg) throws Exception
	{
		mStatLogger.debug("*MonHandler.handleTextMessage");
		mStatLogger.info("{}로 부터 {} 받음", wssCurSession.getId(), tmMsg.getPayload());
		MonVO clsMonVO = MonVO.convert(tmMsg.getPayload());
		
		mStatLogger.debug(" -clsMonVO.getTarget():"+ clsMonVO.getTarget());
		mStatLogger.debug(" -clsMonVO.getMessage():"+ clsMonVO.getMessage());
		
		
		
		Map mpCurParam = wssCurSession.getAttributes();
		String strCurUserId = (String)mpCurParam.get("userId");
		mStatLogger.debug(" - CurUserId:"+ strCurUserId);
		
		
		//연결된 모든 클라이언트에게 메시지 전송
		for(WebSocketSession wssSession : mLstSession)
		{
			Map mpParam = wssSession.getAttributes();
			String strUserId = (String)mpParam.get("userId");
			if(clsMonVO.getTarget().equals(strUserId) == true)
			{
				// 전송대상한테만 메시지를 보낸다.	    	
				wssSession.sendMessage(new TextMessage(clsMonVO.getMessage()));
			}
		}
	}
    
	@Override  
	public void handleTransportError(WebSocketSession wssSession, Throwable exception) throws Exception
	{  
		mStatLogger.debug("*MonHandler.handleTransportError");
		if(wssSession.isOpen() == true) wssSession.close();  
		mLstSession.remove(wssSession);  
	}  
    

	@Override
	public void afterConnectionClosed(WebSocketSession wssSession, CloseStatus status) throws Exception
	{
		mStatLogger.debug("*MonHandler.afterConnectionClosed");
		mStatLogger.info("{} 연결 끊김.", wssSession.getId());
		mLstSession.remove(wssSession);
	}	
}

7. JSP 설정

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>


	
		
		test