노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

 

AndroidStudio에서 Smack4.1 사용하기 ( for OpenFire )

 

 

해당 주제를 다루는 참고 사이트는 2개로 나누어져 있으며, Eclipse기준으로 되어 있어서,

업그레이드가 필요하다.

 

http://www.tutorialsface.com/2015/08/building-your-own-android-chat-messenger-app-similar-to-whatsapp-using-xmpp-smack-4-1-api-from-scratch-part-1/

 

http://www.tutorialsface.com/2015/08/building-your-own-android-chat-messenger-app-similar-to-whatsapp-using-xmpp-smack-4-1-api-from-scratch-part-2/

 


 

먼저 Part1에서 AndroidStudio로 해당 프로젝트에 알맞는 설정을 해보자

 



이후 설정은 Part1 의 내용처럼 수정 작업을 진행하면 된다.

 

다만, 댓글에 Fison이라는 아이디의 글 내용을 참조해야 한다.

 

 

for me to run it, i change this:
1) ActionBarActivity is deprecated. 
    So i use AppCompatActivity in Chats.java.
2) public class MainActivity extends AppCompatActivity 
    instead of ActionBarActivity
3) i made a modification in Activity_Main.xml

-----------------------------------------------------


xmlns:android="http://schemas.android.com/apk..." />















i add  ......  and comment some code inside

4) i made a modification in MainActivity
only comment This

/*
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View view) {
		Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
		.setAction("Action", null).show();
	}
});
*/



Gradle 스크립트에 추가할 부분은 아래 링크를 참조하면 될 것 같다.


https://github.com/igniterealtime/Smack/wiki/Smack-4.1-Readme-and-Upgrade-Guide


-build.gradle ( Project )

-bulid.gradle ( Module )







StakOverflow.com에 올라온 글도 참조 하면 좋을 것 같다.


http://stackoverflow.com/questions/31274020/integrating-smack-with-android-studio-project-for-chat-application

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


 

XMPP Server용 XMPP Client 만들기


 

Openfire의 하위 프로젝트인 Smack ( Client Library) 를 사용하여, 간단한 프로그램을

빌드 할 수 있다.




 

예를들어 Openfire서버가 설치된 장비의 Stress Test용도의 클라이언트가 필요하다면

이럴때 사용하면 좋을 것도 같다.

 

 

Openfire Projects  ( ignite realtime ) : http://www.igniterealtime.org/projects/index.jsp

 

 

Smack 라이브러리를 다운로드 해서 프로젝트에 추가하는 방안도 있지만,

프로젝트 자체를 Maven Project를 생성을 하고 나서, pom.xml에 아래 내용을

채워 주면 자동으로 Library들이 포함되는 방법이 더 좋을 듯 하다.

 

 

	
		
		   org.igniterealtime.smack
		      smack-java7
		      4.1.6
		 
		
		        org.igniterealtime.smack
		        smack-tcp
		        4.1.6
		
		
		        org.igniterealtime.smack
		        smack-im
		        4.1.6
		
		
		        org.igniterealtime.smack
		        smack-extensions
		        4.1.6
		
	  

 

 

package smackMavenClient;

import java.io.IOException;
import java.util.Collection;

import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;

public class smClient implements ChatMessageListener  {

	private AbstractXMPPConnection conn2 ;
	
	private static smClient c ;
	
	public void login(String userName, String password ) throws SmackException, IOException, XMPPException {
		
		XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
				  .setUsernameAndPassword(userName, password)
				  .setServiceName("localhost")
				  .setHost("localhost")
				  .setPort(5222)
				  .build();
		
		conn2 = new XMPPTCPConnection(config);
		conn2.connect();
	}
	
	public static void main(String[] args) throws SmackException, IOException, XMPPException {

		c = new smClient();

		c.login("아이디", "비번");
		c.sendMessage("보내고 싶은 메시지", "친구아이디");
		c.getFriends();
		
	}
	
	public void sendMessage(String message, String to) throws NotConnectedException {
	
		ChatManager cm = ChatManager.getInstanceFor(conn2);
		
		Chat newChat = cm.createChat(to);
		newChat.addMessageListener( this);
		newChat.sendMessage(message);
		
	}


	public void getFriends() {
		
		Roster r = Roster.getInstanceFor(conn2);
		
		Collection entries = r.getEntries();
		
		for ( RosterEntry entry : entries ) {
			System.out.println( entry.toString() );
		}
		
		c.disconnect();

	}
	
	
	
	public void disconnect()
	{
		conn2.disconnect();
	}
	


	public void processMessage(Chat chat, Message message) {
		
		if ( message.getType().equals("chat")) {
			System.out.println("Received message: " + message.getBody() );
		}

	}


}

 

 

샘플 예제가 있는 웹페이지

 

 

https://namalfernando.wordpress.com/2015/12/18/write-xmpp-client-using-smack-api/ 

 

 

 

* XMPP client로 공개된 소스들에 대한 비교표

 

https://en.wikipedia.org/wiki/Comparison_of_XMPP_clients

 

 

designation Operating system File transfer (XEP-0096) Jingle MUC GPG
ChatSecure Android / Apple iOS Yes per Plugin Yes No
Conversations Android Yes Yes Yes Yes
CoyIM Mac OS X, Linux,Windows
Coccinella Cross-platform Yes Yes Yes No
Gajim BSD/Linux/Windows Yes Yes Yes Yes[Note 1]
Jeti/2 Cross-platform(Java) Yes Voice Beta Yes Yes
Jitsi Cross-platform(Java) Yes Yes Yes No
MCabber Linux, Mac OS X,BSD No No Yes Yes
Pidgin Mac OS X, Linux,Windows Yes Yes Yes per Plugin
Psi eCS/Linux/Mac OS X/Solaris/Windows Yes Yes Yes Yes
Tkabber Cross-platform Yes No Yes Yes

  1. Jump up^ since Version 0.15 on Windows

 

 

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


 (2.2) Openfire, 외부 Database 연동 II

 

 

 

Authentication Integration

 

Openfire는 인증 data를 보유한 외부의 database에서 읽어 올 수 있다.

 

The simplest possible integration with a custom external database is authentication integration. Use the following settings to enable authentication integration.

 

provider.auth.className

-- set the value to org.jivesoftware.openfire.auth.JDBCAuthProvider.

jdbcAuthProvider.passwordSQL

-- the SQL String to select a user's password. The SQL statement should contain a single "?" character, which will be dynamically replaced with a username when being executed.

jdbcAuthProvider.passwordType

-- the type of the password. Valid values are


"plain" (the password is stored as plain text)
"md5" (the password is stored as a hex-encoded MD5 hash)
"sha1" (the password is stored as a hex-encoded SHA-1 hash)
"sha256" (the password is stored as a hex-encoded SHA-256 hash)
"sha512" (the password is stored as a hex-encoded SHA-512 hash)
If this value is not set, the password type is assumed to be plain.

 

 

User Integration

 

Openfire는 사용자 data를 보유한 database에서 읽어 올 수 있다.

 

Optionally, Openfire can load user data from your custom database. If you enable user integration you must also enable authentication integration (see above). Use the following settings to enable user integration.

 

provider.user.className

-- set the value to org.jivesoftware.openfire.user.JDBCUserProvider.

jdbcUserProvider.loadUserSQL

-- the SQL statement to load the name and email address of a user (in that order) given a username. The SQL statement should contain a single "?" character, which will be dynamically replaced with a username when being executed.

jdbcUserProvider.userCountSQL

-- the SQL statement to load the total number of users in the database.

jdbcUserProvider.allUsersSQL

-- the SQL statement to load all usernames in the database.

jdbcUserProvider.searchSQL

-- the SQL statement fragment used to search your database for users. the statement should end with "WHERE" -- the username, name, and email fields will then be dynamically appended to the statement depending on the search. If this value is not set, searching will not be enabled.

 

usernameField

-- the name of the username database field, which will be used for searches.

nameField

-- the name of the name database field, which will be used for searches.

emailField

-- the name of the email database field, which will be used for searches.

 

 

 

Group Integration

 

Openfire는 그룹 데이타를 보유한 database에서 읽어 올 수 있다.

 

Openfire can load group data from your custom database. If you enable group integration you must also enable authentication integration; you'll also likely want to enable user integration (see above). Use the following settings to enable group integration.

 

provider.group.className

-- set the value to org.jivesoftware.openfire.group.JDBCGroupProvider.

jdbcGroupProvider.groupCountSQL

-- the SQL statement to load the total number of groups in the database.

jdbcGroupProvider.allGroupsSQL

-- the SQL statement to load all groups in the database.

jdbcGroupProvider.userGroupsSQL

-- the SQL statement to load all groups for a particular user. The SQL statement should contain a single "?" character, which will be dynamically replaced with a username when being executed.

jdbcGroupProvider.descriptionSQL

-- the SQL statement to load the description of a group. The SQL statement should contain a single "?" character, which will be dynamically replaced with a group name when being executed.

jdbcGroupProvider.loadMembersSQL

-- the SQL statement to load all members in a group. The SQL statement should contain a single "?" character, which will be dynamically replaced with a group name when being executed.

jdbcGroupProvider.loadAdminsSQL

-- the SQL statement to load all administrators in a group. The SQL statement should contain a single "?" character, which will be dynamically replaced with a group name when being executed.

 


실제로 수정된 내용이 Openfire AdminConsole에 반영된 결과




원문 : https://www.igniterealtime.org/builds/openfire/docs/latest/documentation/db-integration-guide.html


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Openfire, 외부 Database연동

 

보유한 회원 정보를 활용하는 방법의 핵심적인 내용을 다룹니다.

 

 

기본 참조 글 : Step4 : Integrating Openfire with MySQL

 

이 예제는 웹사이트는 각 사용자의 저장된 정보를 저장하기위해 MySQL를 사용한다고

생각한다. Openfire는 외부 database와 통합(연동)될 수 있으며, 이 경우는 MySQL이다.

 

http://code.tutsplus.com/articles/create-a-flexible-xmpp-chat-for-a-member-based-website-with-flash-and-php--active-9858

 

1) 수정전의 openfire.xml

 

이 파일은 ${OpenfirHome}/conf/ 에 위치하고, 편집기등으로 수정 할 수 있다.

설치후에 Admin 설정을 통해서 기본 Database등이 생성이 되면, 아래와 같을 것 같다.

<?xml version="1.0" encoding="UTF-8"?>
<jive> 

  <adminConsole> 
    <port>9090</port>  
    <securePort>9091</securePort> 
  </adminConsole>  
  <locale>en</locale>

  <stream> 
    <management> 
      <active>true</active>  
      <requestFrequency>5</requestFrequency> 
    </management> 
  </stream>   
   
    org.jivesoftware.database.DefaultConnectionProvider 
    
  <database> 
  <defaultProvider> 
      <driver>org.postgresql.Driver</driver>  
      <serverURL>jdbc:postgresql://localhost:5432/openfire</serverURL>  
      <username encrypted="true">
dcc8c19832c8f0b244bd961d65b78992d7</username>  
      <password encrypted="true">
196a575f8b562224af43454639fe41e6fff7c2</password>  
      <testSQL>select 1</testSQL>  
      <testBeforeUse>false</testBeforeUse>  
      <testAfterUse>false</testAfterUse>  
      <minConnections>5</minConnections>  
      <maxConnections>25</maxConnections>  
      <connectionTimeout>1.0</connectionTimeout> 
  </defaultProvider>  
  </database> 
</jive>

 

2) ofUser(Table)를 대체할 nuser(Table)을 준비

 

기본 제공되는 사용자 정보 Table(ofUser)를 사용하지 않고, 기존 database를 사용

CREATE TABLE nuser
(
  id character varying(20) NOT NULL,
  company_cd character varying(30),
  division_cd character varying(50),
  pwd character varying(32),
  name character varying(30),
  email character varying(50),
  company_nm character varying(40),
  division_nm character varying(40),
  reg_date timestamp,
  CONSTRAINT nuser_pk PRIMARY KEY (id)
)

 

3) Admin Console

 

관리자 페이지내의  System Properties 링크를 클릭 하면, Property Name / Value가 볼 수 있다.

 

 

Add new property value

 

순서대로 아래 Name과 Value를 등록 한다.

 

 

1) jdbcProvider.driver

 

 

 

2) jdbcProvider.connectionString

 

jdbc:mysql://localhost/mycontentsite?user=root&password=xxxxx

 

3) provider.auth.className

 

org.jivesoftware.openfire.auth.JDBCAuthProvider

 

4) jdbcAuthProvider.passwordSQL

 

SELECT pwd FROM nuser WHERE id=?

 

5) jdbcAuthProvider.passwordType

 

md5

 

* jdbcAuthProvider의 Property Value는 hidden으로 보여준다.

 

 

6) admin.authorizedUsernames

 

janedoe@[the server's XMPP domain] ( ex) janedoe@abc.com )

 

7) provider.user.className

 

org.jivesoftware.openfire.user.JDBCUserProvider

 

8) jdbcUserProvicer.loadUserSQL

 

select name, email from nuser where id=?

 

9) jdbcUserProvider.userCountSQL

 

select count(*) from nuser

 

10) jdbcUserProvider.allUsersSQL

 

select id from nuser

 

11) usernameFiled

 

id

 

12) nameField

 

name

 

13) emailField

 

email

 



Admin Console를 로그아웃하고, Openfire를 재시작한다.

admin.authorizedUsernames에 등록된 사용자로 Admin Console에 접속이 된다면, 정상적으로 등록이 된것이다.

 

( openfire 4.0.2 버젼은 수정된 정보가 openfire.xml에 등록되지 않으며, ofProperty Table내에서 해당 정보들을 확인하고 수정이 가능하다.



 

일반 사용자들은 Spark등을 이용해서 새로운 user database정보로 접속 여부를 체크한다.

 

 

 

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

 


Openfire ( 메신저 서버 ) - eclipse에서 빌드하기

 

 

 


 

 

1. 기존 IDE - eclipse, EGit, JDK , Ant

 

2. 소스 download - https://github.com/igniterealtime/Openfire.git

 

3. build  - build/build.xml

 

 

4. run 

1) Run -> Run Configurations 선택

2) Java Application -> New  선택

(1) Main탭

: Name, Project, Main class를 등록Main class는 ServerStarter를 Search )

(2) Arguments탭

: VM arguments를 등록

 

(3) Calsspath 탭

: src/i18n , src/resource/jar , build/lib/dist를 등록

(4) Common 탭

(5) JRE탭 : 1.8를 선택

 

5. installer - build/installer/openfire.install4j

 


원문 : https://community.igniterealtime.org/docs/DOC-1020 

 

 

 


* Spark ( 메신저 클라이언트) - eclipse에서 빌드하기

 

 

 

 

 

1. 기존 IDE - eclipse , EGit, JDK, Ant

 

2. 소스 download - https://github.com/igniterealtime/Spark.git

 

3. build  - build/build.xml

 

4. run 

1) Run -> Run Configurations 선택

 

2) Java Application -> New  선택

 

(1) Main탭

: Name, Project, Main class를 등록Main class는 Startup를 Search )

 

(2) Calsspath 탭

: src/resources를 등록

 

(3) JRE탭 : 1.8를 선택

 

5. installer - build/installer/spark.install4j

 

설치본의 위치를 변경하는 부분

 

원문 : https://community.igniterealtime.org/docs/DOC-5180

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Spark (메신저 클라이언트) - 스킨 변경

 

 

 

1. 이미지

 

 

1) 대상 위치

 

Spark/src/resources/images 또는 target/classes/images

 

2) 변경 대상들

 

새로운 이미지를 아래 대상들과 같이 동일 W*H사이즈, 동일 file포맷으로 작성하여

overwrite(update)를 진행하면 된다.

 

 

2. 문자열

 

1) 대상 위치

 

Spark/src/java밑에 org.jivesoftware.resource

또는 target/classes밑에 org.jivesoftware.resource

 

2) 1차 변경 대상 파일들

 

(1) default.properties

(2) configuration.properties

(3) spark.properties

 

3) 2차 변경 대상 파일들

 

(1) build/build.xml

(2) src/resources/i18n/spark_i18n.properties

(3) src/java/org.jivesoftware.launcer.Installer.java

 

 

 

 

*참조글 : https://community.igniterealtime.org/docs/DOC-1360

 

Apache Ant와 install4j를 설치하여, 기존 이미지와 문자열을 수정하여, Spark를 재빌드하는 과정을 정리 해 놓았다.

 

 

3. 메뉴 hidden 처리

 

일부 메뉴는 hidden처리 하는 것이 좋을 수도 있다.

 

 

 

참고로 아래는 변경을 해 본 이미지 결과물 입니다.

 

 

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

 

(1) 소개 - Openfire ( 메신저 서버 ) ?




이것은, 그룹웨어처럼 보유한 회원 정보로 연동되는 메신저를 만들수 있다.

 

1) 기존 회원을 보유한 경우 - 해당 정보를 사용하거나 활용

2) 기본적으로 데스크탑 메신저를 제공

3) 모바일용 메신저를 위한 라이브러리 제공 ( 공개된 오픈 소스 클라이언트를 바로 사용 )

 

4) 전용화(rebrand)를 한다면 필요한 것들은 ...

(1) 클라이언트 rebrand (Naming변경 및 이에 따른 Design 변경 적용)

(2) 오픈형 가입(signup)은 block, 전용 가입 창구 마련

(3) 오픈형 클라이언트의 접근을 제한하기 위한 packet변경

(4) 변경된 Packet과 다르면 차단하는 Filter 모듈 제작

 

 


Openfire란

 



 

크로스 플랫폼(또는 멀티 플래폼)을 지원하며, 실시간으로 협업(RTC)을 하도록 도와주는 서버로, 오픈 소스 아파치 라이센스를 따른다.

 

- 제공 platform : Mac OS X, Windows , Redhat / CentOS, Debian /Ubuntu

 

인스턴스 메시징을 위해서 오픈 프로토콜로 예전에 Jabber라고 부르던 XMPP를 사용하며,

설치와 관리가 쉽고, 견고한 보안과 성능을 제공한다.

 

- 커뮤니티 사이트 ignite realtime : Jive Software의 오픈 소스 실시간 커뮤니케이션 프로젝트의 사용자와 개발자를 위한 사이트



http://www.igniterealtime.org/projects/openfire/index.jsp



 

 

추가 프로젝트

 

 

완성된 데스크톱용 Client로 제공되는 Spark 프로젝트(Java)

직접 Client를 제작할떄 필요한 Java Client Library로 제공되는 Smack프로젝트가 있다.

 

 

관련 프로젝트

 

Tinder : 자바 XMPP 라이브러리, XMPP stanza와 component를 구현하도록 제공

Whack : 쉽게 사용 가능한 자바 XMPP 콤포넌트 라이브러리

 

중단 프로젝트

 

XIFF : Flash XMPP client library

SparkWeb : Web based real-time collaboration client

 


http://www.igniterealtime.org/projects/index.jsp





 

실행화면

 

1. 관리자 콘솔

 

2. 클라이언트 실행 화면

 

 

 

 

 

2. 설치본 설치 가이드 / Installation

 

 

Windows , 윈도우


 

Run the Openfire installer. The application will be installed to C:\Program Files\Openfire by default.


오픈파이어 인스톨러를 실행한다. 어플리케이션은 기본적으로 C:\Program Files\Openfire에

에 설치가 된다.

 

Note: If you are installing Openfire on Windows Vista/Windows 7/Windows Server 2008 or newer Windows version and you have UAC protection enabled, then we suggest to choose other installation folder than Program files (e.g. C:\Openfire).

Otherwise you will have to run Openfire launcher with Run as administrator option, because Openfire is storing its configuration (and the embedded database if used) in the installation folder and UAC protection will cause errors on startup, when running without elevated privileges.

 



Linux/Unix , 리눅스/유닉스



Choose either the RPM or tar.gz build. 


RPM 또는 tar.gz 설치본중에서 선택하라.



If using the RPM, run it using your package manager to install Openfire to /opt/openfire:


    rpm -ivh openfire_X_Y_Z.rpm



If using the .tar.gz, extract the archive to /opt or /usr/bin:


    tar -xzvf openfire_X_Y_Z.tar.gz

    mv openfire /opt

 

Note: the .tar.gz build does not contain a bundled Java runtime (JRE). Therefore, you must have JDK or JRE 1.7.0 or later installed on your system. You can check your java version by typing "java -version" at the command line and (if necessary) upgrade your Java installation by visiting java.com.

 


> Running Openfire in Linux/Unix, - RPM


If you are running on a Red Hat or Red Hat like system (CentOS, Fedora, etc), we recommend using the RPM as it contains some custom handling of the standard Red Hat like environment. Assuming that you have used the RPM, you can start and stop Openfire using the /etc/init.d/openfire script.


# /etc/init.d/openfire


Usage /etc/init.d/openfire {start|stop|restart|status|condrestart|reload}


# /etc/init.d/openfire start



> Starting openfire: - .tar.gz 


If you are running on a different Linux/Unix varient, and/or you have used the .tar.gz 'installer', you can start and stop Openfire using the bin/openfire script in your Openfire installation:


# ./openfire
Usage: ./openfire {start|stop}

# ./openfire start
Starting openfire

 

 

설치 가이드

http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/install-guide.html

 

 


* 구축사례 :


소개 : 농협 정보 시스템 / 공개 SW로 사내 메신저 개발

 

 

 

 

http://www.oss.kr/oss_repository10/535682 





* 기타 설정 설명 자료


: openfire 설치본을 설치후에 관리자 콘솔 설정 내용

 

https://www.javacodegeeks.com/2010/08/openfire-server-installation.html

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,