This chapters explains how to create a simple application step-by step with samples. The usual scenario to get it to work is:
- Create a session (initiator or acceptor)
- Send a message, process incoming messages
- Close the session
Session acceptor creation
Session-acceptor is created in the following way:
- FIXServer object is created (server)
- Port and other server properties are set
- FIXServerListener object is created (observer entity for new sessions) and set
- As soon as someone tries to establish a connection to your FIX server by sending a Logon message you will receive a callback to your FIXServerListener interface with a new FIXSession object. Most of the SessionParameters will be prepopulated based on the incoming Logon
- You may either reject this particular incoming session by calling dispose() or accept incoming session by calling connect(). Prior to the connect() call set, your FIXSessionListener (observer entity for session to receive session specific events)
public class SimpleServer implements FIXServerListener {
private List
<FIXSession> activeSessions = new ArrayList
<FIXSession>();
public static void main(String[] args) throws IOException {
FIXServer server = new FIXServer();
server.setPort(777);
server.setListener(new SimpleServer());
server.start();
System.out.println("Press enter to exit");
System.in.read();
server.stop();
}
public void newFIXSession(FIXSession session) {
try {
activeSessions.add(session);
session.setFIXSessionListener(new MyFIXSessionListener(session));
session.connect();
} catch (IOException e) {
}
}
private class MyFIXSessionListener implements FIXSessionListener {
private FIXSession session;
public MyFIXSessionListener(FIXSession session) {
this.session = session;
}
public void onSessionStateChange(SessionState sessionState) {
if (SessionState.DISCONNECTED == sessionState) {
activeSessions.remove(session);
}
}
public void onNewMessage(FIXFieldList message) {
}
}
}
Session initiator creation
Session-initiator is created in three steps:
- Application object is created (observer entity for session to receive events)
- The session object is created passing the initiator's specific parameters
- The connect method is called
SessionParameters details = new SessionParameters();
details.setFixVersion(FIXVersion.FIX42);
details.setHost("localhost");
details.setHeartbeatInterval(30);
details.setPort(777);
details.setSenderCompId("senderId");
details.setTargetCompId("targetId");
FIXSessionListener application = new FIXSessionListener() {
public void onSessionStateChange(SessionState sessionState) {
System.out.println("Session state changed:" + sessionState);
}
public void onNewMessage(FIXFieldList message) {
System.out.println("New application level message type: " + message.getTagValueAsString(FIXT11.Header.MsgType) +
"received");
}
};
final FIXSession session = details.createNewFIXSession();
session.setFIXSessionListener(application);
session.connect();
Creating new order
FIX Antenna provides two interfaces for manipulations with FIX messages:
- Flat model
- Object model
The flat model is based on a single FIXFieldList class and exports high performance.
FIXFieldList messageContent = new FIXFieldList();
messageContent.addTag(11, "USR20000101");
messageContent.addTag(54, 1);
messageContent.addTag(60, "20000101-01:12:55");
The object model is a typified interface less efficient than the flat model, but more user-friendly.
NewOrderSingle order = new NewOrderSingle();
order.getHeader().setBeginString(FIXVersion.FIX44.getMessageVersion());
order.getHeader().setMsgType("D");
order.setClOrdID( "USR20000101" );
String clOrdID = order.getClOrdID();
Sending order
Message is sent asynchronously by calling the session.sendMessage method. Consequently the message is scheduled for sending in the internal queue and sent in a separate thread. This means that if the method returns control, the message is not necessarily already sent. The fastest standard way of sending a message out is to use the sendMessage(String messageType, FIXFieldList content) method. This message adds proper footer and header.
session.sendMessage("B", messageContent);
Alternatively, if a user has entire FIXMessage in FIXFieldList including header and footer, it is possible to use the sendMessage(FIXFieldList message) method. Header and footer fields will be updated but it will take more time then just to wrap message content, so the first option is preferred.
session.sendMessage(message);
Processing incoming message
Implement the FIXSessionListener interface to process incoming messages and session changes:
private class MyFIXSessionListener implements FIXSessionListener {
private FIXSession session;
public MyFIXSessionListener(FIXSession session) {
this.session = session;
}
public void onSessionStateChange(SessionState sessionState) {
if (SessionState.DISCONNECTED == sessionState) {
activeSessions.remove(session);
}
}
public void onNewMessage(FIXFieldList message) {
log.debug("New app message type " + new String(message.getMsgType()) + "received for session" + session.toString());
}
}
The FIXSessionListener.onNewMessage() method is called only in case of the delivery of an incoming application-level message, if all checks are passed. Possible errors and all session-level messages are handled inside the FIXEngine. The FIXEngine guarantees sequential message delivery in the order of receiving.
Note: It is possible to provide custom session level handlers if desired, but it may affect FIXEngine workflow and the FIX protocol support so it is not recommended unless absolutely necessary.
Note: the FIXSessionListener.onNewMessage method must not be dead-locked or perform time-demanding operations, because it will lock entire message processing for this session. A user should execute time consuming handling operations in separate threads and return control as soon as possible..
Closing session
Use the following methods to close the session:
session.disconnect("User request");
A user should dispose session if he don't plan to use this instance again.
Sample application
Combining all above:
package com.epam.example;
import com.epam.fix.message.FIXFieldList;
import com.epam.fixengine.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SimpleServer implements FIXServerListener {
public static void main(String[] args) throws IOException {
FIXServer server = new FIXServer();
server.setPort(777);
server.setListener(new SimpleServer());
server.start();
System.out.println("Server started...");
System.in.read();
server.stop();
}
public void newFIXSession(FIXSession session) {
try {
session.setFIXSessionListener(new MyFIXSessionListener(session));
session.connect();
System.out.println("New connection accepted");
} catch (IOException e) {
}
}
private class MyFIXSessionListener implements FIXSessionListener {
private FIXSession session;
public MyFIXSessionListener(FIXSession session) {
this.session = session;
}
public void onSessionStateChange(SessionState sessionState) {
System.out.println("Session state: " + sessionState);
if (SessionState.DISCONNECTED == sessionState) {
session.dispose();
System.out.println("Your session has been disconnected. Press ENTER to exit the programm.");
}
}
public void onNewMessage(FIXFieldList message) {
System.out.println("New message is accepted: " + message.toString());
}
}
}
package com.epam.example;
import com.epam.common.FIXVersion;
import com.epam.fix.message.FIXFieldList;
import com.epam.fix.message.constants.FIXT11;
import com.epam.fixengine.*;
import java.io.IOException;
public class SimpleNewsBroadcaster {
public static void main(String[] args) throws IOException {
SessionParameters details = new SessionParameters();
details.setFixVersion(FIXVersion.FIX42);
details.setHost("localhost");
details.setHeartbeatInterval(30);
details.setPort(777);
details.setSenderCompId("senderId");
details.setTargetCompId("targetId");
final FIXSession session = details.createNewSession();
FIXSessionListener application = new FIXSessionListener() {
public void onSessionStateChange(SessionState sessionState) {
System.out.println("Session state changed:" + sessionState);
if (sessionState == SessionState.DISCONNECTED) {
session.dispose();
}
}
public void onNewMessage(FIXFieldList message) {
System.out.println("New application level message type: " +
message.getTagValueAsString(FIXT11.Header.MsgType) + "received");
}
};
session.setFIXSessionListener(application);
session.connect();
FIXFieldList messageContent = new FIXFieldList();
messageContent.addTag(148, "Hello there");
messageContent.addTag(33, 3);
messageContent.addTag(58, "line1");
messageContent.addTag(58, "line2");
messageContent.addTag(58, "line3");
session.sendMessage("B", messageContent);
try {
Thread.sleep(100);
} catch (Exception e) {
}
session.disconnect("User request");
}
}